home *** CD-ROM | disk | FTP | other *** search
/ The Arcade BBS / arcadebbs.zip / arcadebbs / bbstools / WWIV Mods / COMMON21.ZIP / COMMON.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-13  |  80.9 KB  |  3,645 lines

  1. // ************************************************************************* //
  2. // Begin COMMON mod, functions that are common among many Asylum releases    //
  3. // If you get a duplicate function error, then you have it installed twice   //
  4. // remove your oldest duplicated functions.                                  //
  5. // ************************************************************************* //
  6.  
  7. /* *********************************************************************** */
  8. /* Asylum COMMON - by Michael Deweese Copyright 1994                       */
  9. /*                                                                         */
  10. /* You may use this code in WWIV as installed under the COMMON.MOD file    */
  11. /* You may not use this code in your own programs without the consent of   */
  12. /* Michael Deweese.                                                        */
  13. /* You can call these functions from your own WWIV modifications, but may  */
  14. /* not rip these out and include them in your mod.  In other words, to     */
  15. /* access these functions, the user using your modification must have      */
  16. /* mod installed                                                           */
  17. /*                                                                         */
  18. /* Again, feel free to make mods requiring COMMON to be installed, just    */
  19. /* as I do, but I really don't want these function ripped apart and        */
  20. /* and included in individual mods, and it would make it impossible for me */
  21. /* to maintain them.                                                       */
  22.  
  23.  
  24. #include "vars.h"
  25. #include <stdarg.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <errno.h>
  30. #include <ctype.h>
  31. #include <conio.h>
  32.  
  33. // Makes the side menu to look fancy, show the hot char in a different color
  34. // and will make sure the cursor is in a nice place, may be a little slower
  35. // for 2400 bps callers
  36. #define FANCY_LIST
  37.  
  38.  
  39. int numlock=NOTNUMBERS;
  40.  
  41. unsigned char pd_getkey(void)
  42. {
  43.   unsigned char ch;
  44.   int beepyet;
  45.   long dd,tv,tv1;
  46.  
  47.   tleft(1);
  48.   
  49.   beepyet = 0;
  50.   timelastchar1=timer1();
  51.  
  52.   if (so())
  53.     tv=10920L;
  54.   else
  55.     tv=3276L;
  56.  
  57.   tv1=tv/2;
  58.  
  59.   lines_listed = 0;
  60.   do
  61.   {
  62.     while (empty() && !hangup)
  63.     {
  64.       dd = timer1();
  65.       if ((dd<timelastchar1) && ((dd+1000)>timelastchar1))
  66.         timelastchar1=dd;
  67.       if (labs(dd - timelastchar1) > 65536L)
  68.         timelastchar1 -= 1572480L;
  69.       if (((dd - timelastchar1) > tv1) && (!beepyet))
  70.       {
  71.         beepyet = 1;
  72.         outchr(7);
  73.       }
  74.       if (labs(dd - timelastchar1) > tv)
  75.       {
  76.         nl();
  77.         outstr("2Log off due to inactivity...Call back later when you are there.");
  78.         nl();
  79.         hangup = 1;
  80.       }
  81.       checkhangup();
  82.     }
  83.     ch = pd_inkey();
  84.   } while (!ch && !in_extern && !hangup);
  85.   if (checkit && (ch > 127)) {
  86.     checkit = 0;
  87.     ch = ch & (andwith = 0x7F);
  88.   }
  89.   return(ch);
  90. }
  91.  
  92.  
  93. char pd_inkey(void)
  94. {
  95.   char ch=0;
  96.   
  97.   tleft(1);
  98.  
  99.   if (x_only)
  100.     return(0);
  101.  
  102.   if (charbufferpointer) {
  103.     if (!charbuffer[charbufferpointer])
  104.       charbufferpointer = charbuffer[0] = 0;
  105.     else
  106.       return(charbuffer[charbufferpointer++]);
  107.   }
  108.   if (kbhitb() || (in_extern == 2)) {
  109.     ch = getchd1();
  110.     lastcon = 1;
  111.     if (!ch) {
  112.       if (in_extern)
  113.         in_extern = 2;
  114.       else {
  115.         ch = getchd1();
  116.         skey(ch);
  117.         ch = (((ch == 68) || (ch==103)) ? 2 : 0);
  118.       }
  119.     } else if (in_extern)
  120.       in_extern = 1;
  121.     timelastchar1=timer1();
  122.   } else if (incom && comhit()) {
  123.     ch = (get1c() & andwith);
  124.     lastcon = 0;
  125.   }
  126.   return(ch);
  127. }
  128.  
  129. unsigned side_menu(int *menu_pos, int redraw, char *menu_items[], int xpos, int ypos, struct side_menu_colors *smc)
  130. {
  131.   static int positions[20], amount=1;
  132.   int x;
  133.   unsigned event;
  134.  
  135.   tleft(1);
  136.   
  137.   if(redraw)
  138.   {
  139.     amount=1;
  140.     positions[0]=xpos;
  141.     while(menu_items[amount] && menu_items[amount][0] && !hangup )
  142.     {
  143.       positions[amount]=positions[amount-1]+strlen(menu_items[amount-1])+2;
  144.       ++amount;
  145.     }
  146.     
  147.     x=0;
  148.     setc(smc->normal_menu_item);
  149.  
  150.     while(menu_items[x] && menu_items[x][0] && !hangup)
  151.     {
  152.       GOTO_XY(positions[x], ypos);
  153.       
  154.       if(*menu_pos==x)
  155.       {
  156. #ifdef FANCY_LIST
  157.         setc(smc->current_highlight);
  158.         outchr(menu_items[x][0]);
  159.         setc(smc->current_menu_item);
  160.         outstr(menu_items[x]+1);
  161. #else        
  162.         setc(smc->current_menu_item);
  163.         outstr(menu_items[x]);
  164.         setc(smc->nomal_menu_item); // This #else only resets colors because fancy will take care of it self... just leave me here...
  165. #endif
  166.       }
  167.       else
  168. #ifdef FANCY_LIST        
  169.       {
  170.         setc(smc->normal_highlight);
  171.         outchr(menu_items[x][0]);
  172.         setc(smc->normal_menu_item);
  173.         outstr(menu_items[x]+1);
  174.       }
  175. #else      
  176.         outstr(menu_items[x]);
  177. #endif        
  178.         
  179.       ++x;
  180.     }
  181.   }
  182.   
  183.   
  184.   
  185.   setc(smc->normal_menu_item);
  186.  
  187.   while(!hangup)
  188.   {
  189.     event=get_kb_event();
  190.  
  191.        /* help       special command    help         extended key */
  192.     if(event==CO || event == SPACE || event == '?' || event==EXECUTE || event==GET_OUT || event == HELP || event == HOTKEY)
  193.       return event;
  194.     
  195.       
  196.     if(event<128)
  197.     {
  198.       int x=0;
  199.       while(menu_items[x] && menu_items[x][0] && !hangup)
  200.       {
  201.         if(event==toupper(menu_items[x][0]) || event==tolower(menu_items[x][0]))
  202.         {
  203.           GOTO_XY(positions[*menu_pos], ypos);
  204. #ifdef FANCY_LIST
  205.           setc(smc->normal_highlight);
  206.           outchr(menu_items[*menu_pos][0]);
  207.           setc(smc->normal_menu_item);
  208. #endif
  209.           outstr(menu_items[*menu_pos]+1);
  210.  
  211.           *menu_pos=x;
  212.           
  213. #ifdef FANCY_LIST
  214.           setc(smc->current_highlight);
  215.           GOTO_XY(positions[*menu_pos], ypos);
  216.           outchr(menu_items[*menu_pos][0]);
  217.           setc(smc->current_menu_item);
  218.           outstr(menu_items[*menu_pos]+1);
  219. #else      
  220.           setc(smc->current_menu_item);
  221.           GOTO_XY(positions[*menu_pos], ypos);
  222.           outstr(menu_items[*menu_pos]);
  223.           setc(smc->normal_menu_item);
  224. #endif                    
  225.           
  226. #ifndef FANCY_LIST          
  227.           // Don't waist time putting the cursor in a nice pos at slow speeds
  228.           if(modem_speed>2400 || !using_modem)
  229. #endif            
  230.             GOTO_XY(positions[*menu_pos], ypos);
  231.           
  232.           return(EXECUTE);
  233.         }
  234.         ++x;
  235.       }
  236.     }
  237.     else
  238.     {
  239.       switch(event)
  240.       {
  241.         case COMMAND_LEFT:
  242.           GOTO_XY(positions[*menu_pos], ypos);
  243. #ifdef FANCY_LIST        
  244.             setc(smc->normal_highlight);
  245.             outchr(menu_items[*menu_pos][0]);
  246.             setc(smc->normal_menu_item);
  247.             outstr(menu_items[*menu_pos]+1);
  248. #else      
  249.           outstr(menu_items[*menu_pos]);
  250. #endif
  251.           if(!*menu_pos)
  252.             *menu_pos=amount-1;
  253.           else
  254.             --*menu_pos;
  255.             
  256. #ifdef FANCY_LIST        
  257.             setc(smc->current_highlight);
  258.             GOTO_XY(positions[*menu_pos], ypos);
  259.             outchr(menu_items[*menu_pos][0]);
  260.             setc(smc->current_menu_item);
  261.             outstr(menu_items[*menu_pos]+1);
  262. #else      
  263.           setc(smc->current_menu_item);
  264.           GOTO_XY(positions[*menu_pos], ypos);
  265.           outstr(menu_items[*menu_pos]);
  266.           setc(smc->normal_menu_item);
  267. #endif                    
  268.           
  269. #ifndef FANCY_LIST          
  270.           // Don't waist time putting the cursor in a nice pos at slow speeds
  271.           if(modem_speed>2400 || !using_modem)
  272. #endif            
  273.             GOTO_XY(positions[*menu_pos], ypos);
  274.  
  275.           
  276.           break;
  277.           
  278.         case COMMAND_RIGHT:
  279.           GOTO_XY(positions[*menu_pos], ypos);
  280. #ifdef FANCY_LIST        
  281.             setc(smc->normal_highlight);
  282.             outchr(menu_items[*menu_pos][0]);
  283.             setc(smc->normal_menu_item);
  284.             outstr(menu_items[*menu_pos]+1);
  285. #else      
  286.           outstr(menu_items[*menu_pos]);
  287. #endif          
  288.           if(*menu_pos==amount-1)
  289.             *menu_pos=0;
  290.           else
  291.             ++*menu_pos;
  292.             
  293. #ifdef FANCY_LIST        
  294.             setc(smc->current_highlight);
  295.             GOTO_XY(positions[*menu_pos], ypos);
  296.             outchr(menu_items[*menu_pos][0]);
  297.             setc(smc->current_menu_item);
  298.             outstr(menu_items[*menu_pos]+1);
  299. #else      
  300.           setc(smc->current_menu_item);
  301.           GOTO_XY(positions[*menu_pos], ypos);
  302.           outstr(menu_items[*menu_pos]);
  303.           setc(smc->normal_menu_item);
  304. #endif          
  305.             
  306. #ifndef FANCY_LIST          
  307.           // Don't waste time putting the cursor in a nice pos at slow speeds
  308.           if(modem_speed>2400 || !using_modem)
  309. #endif            
  310.             GOTO_XY(positions[*menu_pos], ypos);
  311.  
  312.           
  313.           break;
  314.           
  315.         default:
  316.           return(event);
  317.           
  318.       }
  319.     }
  320.   } // While !hangup   
  321.   return(0);      
  322. }          
  323.  
  324. // Set up a new control break handler so that my getch's won't break out of the bbs
  325. int new_control_break(void)
  326. {
  327.   sysoplog("Control Break pressed.  Program NOT aborting");
  328.   return 1;
  329. }
  330.  
  331. unsigned get_kb_event(void)
  332. {
  333.   time_t time1, time2;
  334.   unsigned key;
  335.  
  336.   ctrlbrk(new_control_break); // Disable control break
  337.   
  338.   tleft(1);
  339.   time(&time1);
  340.   
  341.  
  342.   
  343.   do{
  344.     time(&time2);
  345.     if(difftime(time2,time1) > 180 ) // greater than 3 minutes
  346.     {
  347.       hangup=1;
  348.       return 0;
  349.     }
  350.     if(hangup)
  351.       return 0;
  352.  
  353.     if(comhit() || kbhit())
  354.     {
  355.       if(!incom || kbhit())   // Check for local keys
  356.       {
  357.         key=getch();
  358.  
  359.         if(key==127)
  360.           return(COMMAND_DELETE);
  361.         if(key==22)
  362.           return(COMMAND_INSERT);
  363.  
  364.  
  365.         if(key==13 || key==12)
  366.         {
  367.           return(EXECUTE);
  368.         }
  369.         
  370.  
  371.         if(!key)
  372.         {
  373.           if(kbhit())
  374.           {
  375.             key=getch();
  376.             return(key<<4);
  377.           }
  378.         }
  379.         else 
  380.         {
  381.           if(numlock==NOTNUMBERS)
  382.           {
  383.             switch(key)
  384.             {
  385.               case '8':
  386.                 return(COMMAND_UP);
  387.               case '4':
  388.                 return(COMMAND_LEFT);
  389.               case '2':
  390.                 return(COMMAND_DOWN);
  391.               case '6':
  392.                 return(COMMAND_RIGHT);
  393.               case '0':
  394.                 return(COMMAND_INSERT);
  395.               case '.':
  396.                 return(COMMAND_DELETE);
  397.               case '9':
  398.                 return(COMMAND_PAGEUP);
  399.               case '3':
  400.                 return(COMMAND_PAGEDN);
  401.               case '7':
  402.                 return(COMMAND_HOME);
  403.               case '1':
  404.                 return(COMMAND_END);
  405.             }
  406.           } 
  407.           switch(key)
  408.           {
  409.             case TAB:
  410.               return(TAB); 
  411.             case ESC:
  412.               return(GET_OUT);
  413.             default:
  414.             {
  415.               return(key);
  416.             }
  417.           }
  418.         }
  419.       }
  420.       else if(comhit())
  421.       {
  422.         key=pd_getkey();
  423.  
  424.         if(key==127)
  425.           return(COMMAND_DELETE);
  426.         if(key==22)
  427.           return(COMMAND_INSERT);
  428.  
  429.  
  430.  
  431.         if(key==13 || key==12)
  432.         {
  433.           return(EXECUTE);
  434.         }
  435.         
  436.         else if(key==ESC)
  437.         {
  438.           time_t time1;
  439.           time_t time2;
  440.  
  441.           time(&time1);
  442.           time(&time2);
  443.  
  444.           do
  445.           {
  446.             time(&time2);
  447.  
  448.             if(comhit())
  449.             {
  450.               key=pd_getkey();
  451.               if(key==OB||key==O)
  452.               {
  453.                 key=pd_getkey();
  454.  
  455.                 // Check for a second set of brackets
  456.                 if(key==OB||key==O)
  457.                   key=pd_getkey();
  458.  
  459.                 switch(key)
  460.                 {
  461.                   case A_UP:
  462.                     return(COMMAND_UP);
  463.                   case A_LEFT:
  464.                     return(COMMAND_LEFT);
  465.                   case A_DOWN:
  466.                     return(COMMAND_DOWN);
  467.                   case A_RIGHT:
  468.                     return(COMMAND_RIGHT);
  469.                   case A_INSERT:
  470.                    return(COMMAND_INSERT);
  471.                   case A_DELETE:
  472.                    return(COMMAND_DELETE);
  473.                   case A_HOME:
  474.                     return(COMMAND_HOME);
  475.                   case A_END:
  476.                     return(COMMAND_END);
  477.  
  478.                   default:
  479.                    return(key);
  480.                 }
  481.               }
  482.               else
  483.                 return(GET_OUT);
  484.             }
  485.           } while(difftime(time2,time1) < 1 && !hangup);
  486.  
  487.           if(difftime(time2,time1) >= 1)  // if no keys followed ESC
  488.             return(GET_OUT);
  489.         }
  490.         else
  491.         {
  492.  
  493.           if(!key)
  494.           {
  495.             if(kbhit())
  496.             {
  497.               key=getch();
  498.               return(key<<4);
  499.             }
  500.           }
  501.  
  502.  
  503.           if(numlock==NOTNUMBERS)
  504.           {
  505.             switch(key)
  506.             {
  507.               case '8':
  508.                 return(COMMAND_UP);
  509.               case '4':
  510.                 return(COMMAND_LEFT);
  511.               case '2':
  512.                 return(COMMAND_DOWN);
  513.               case '6':
  514.                 return(COMMAND_RIGHT);
  515.               case '0':
  516.                 return(COMMAND_INSERT);
  517.               case '.':
  518.                 return(COMMAND_DELETE);
  519.               case '9':
  520.                 return(COMMAND_PAGEUP);
  521.               case '3':
  522.                 return(COMMAND_PAGEDN);
  523.               case '7':
  524.                 return(COMMAND_HOME);
  525.               case '1':
  526.                 return(COMMAND_END);
  527.             }
  528.           }  
  529.           switch(key)
  530.           {
  531.             default:
  532.               return(key);
  533.           }
  534.         }
  535.       }
  536.       time(&time1);  // reset timer
  537.     }
  538.     else
  539.       giveup_timeslice();
  540.     
  541.   }while(!hangup);
  542.   return 0; // must have hung up
  543. }
  544.  
  545.  
  546.  
  547. // Like onek but does not put cursor down a line
  548. // One key, no carriage return
  549. char onek_ncr(char *s)
  550. {
  551.   char ch;
  552.  
  553.   while (!strchr(s, ch = upcase(getkey())) && !hangup)
  554.     ;
  555.   if (hangup)
  556.     ch = s[0];
  557.   outchr(ch);
  558.   return (ch);
  559. }
  560.  
  561.  
  562. int do_sysop_command(unsigned command)
  563. {
  564.   unsigned x;
  565.   int needredraw=0;
  566.  
  567.   switch(command)
  568.   {
  569.     // Commands that cause screen to need to be redrawn go here
  570.     case COMMAND_F1:
  571.     case COMMAND_CF1:
  572.     case COMMAND_CF9:
  573.     case COMMAND_F10:
  574.     case COMMAND_CF10:
  575.       needredraw=1;
  576.       x=command>>4;
  577.       break;
  578.  
  579.     // Commands that don't change the screen around
  580.     case COMMAND_SF1:
  581.     case COMMAND_F2:
  582.     case COMMAND_SF2:
  583.     case COMMAND_CF2:
  584.     case COMMAND_F3:
  585.     case COMMAND_SF3:
  586.     case COMMAND_CF3:
  587.     case COMMAND_F4:
  588.     case COMMAND_SF4:
  589.     case COMMAND_CF4:
  590.     case COMMAND_F5:
  591.     case COMMAND_SF5:
  592.     case COMMAND_CF5:
  593.     case COMMAND_F6:
  594.     case COMMAND_SF6:
  595.     case COMMAND_CF6:
  596.     case COMMAND_F7:
  597.     case COMMAND_SF7:
  598.     case COMMAND_CF7:
  599.     case COMMAND_F8:
  600.     case COMMAND_SF8:
  601.     case COMMAND_CF8:
  602.     case COMMAND_F9:
  603.     case COMMAND_SF9:
  604.     case COMMAND_SF10:
  605.       needredraw=0;
  606.       x=command>>4;
  607.       break;
  608.       
  609.     default:
  610.       x=0;
  611.       break;
  612.   }
  613.       
  614.   if(x)
  615.   {
  616.     if(needredraw)
  617.       CLS();
  618.  
  619.     skey(x);
  620.  
  621.     if(needredraw)
  622.       CLS();
  623.   }
  624.   
  625.   return(needredraw);
  626. }
  627.  
  628.  
  629.  
  630.  
  631. // All the different functions that output strings to the screen and com
  632. // buffer, all of these need to be modifed to get the following color in
  633. // These don't count functions like npr and prt, since they end up calling
  634. // outstr to do the string printing... wonder if Wayne thinks he needs any
  635. // more functions to print string... hmmm....
  636. // outstr  OutString (COM.C)
  637. // pla     Print Line with Abort (BBSUTL.C)
  638. // plal    Print Line with Abort and Limit how much can be printed hmm npr... (BBSUTL.C)
  639. // osan    OutString with Abort and Next (MSGBASE.C)
  640. // plan    Print Line with Abort and Next (MSGBASE.C)
  641.  
  642. // Oh, colors are...
  643. // |00 - |15 regular dos foreground colors
  644. // |16 - |23 OR |b0- |b7 for regular dos background colors
  645. // There MUST be two numbers following the pipe, ie |01 NOT |1
  646. void colorize_text(char *buffer)
  647. {
  648.   int pos=0, fmt_pos=0;
  649.   int attrib, col;
  650.   char num[3];
  651.   char *formated;
  652.   char color[50];
  653.   unsigned long x;
  654.  
  655.  
  656.   x=strlen(buffer);
  657.   x=(x)+100;
  658.  
  659.   formated=(char *)malloca(x);
  660.   if(!formated)
  661.   {
  662.     sysoplog("No mem to color text");
  663.     return;
  664.   }
  665.   formated[0]=0;
  666.  
  667.  
  668.   while(buffer[fmt_pos] && pos < x)
  669.   {
  670.     if(buffer[fmt_pos]=='|')
  671.     {
  672.       if(isdigit(buffer[fmt_pos+1]) || buffer[fmt_pos+1]==' ')
  673.       {
  674.         if(isdigit(buffer[fmt_pos+2]) || (buffer[fmt_pos+2]==' ' && buffer[fmt_pos+1]!=' '))
  675.         {
  676.  
  677.           if(buffer[fmt_pos+1]!='b' || buffer[fmt_pos+1]=='B')
  678.           {
  679.             strncpy(num, buffer+fmt_pos+1, 2);
  680.             num[2]=0;
  681.             col=atoi(num);
  682.  
  683.             if(col<16)
  684.             {
  685.               attrib=col;
  686.               buildfor(attrib, color);
  687.             }
  688.             else // For background colors 16-23)
  689.             {
  690.               col-=16;
  691.               attrib=col;
  692.               buildback(attrib, color);
  693.             }
  694.  
  695.             fmt_pos+=3;
  696.             strcat(formated, color);
  697.             pos+=strlen(color);
  698.           }
  699.           else if(buffer[fmt_pos+1]=='b' || buffer[fmt_pos+1]=='B')
  700.           {
  701.             strncpy(num, buffer+fmt_pos+2, 1);
  702.             num[1]=0;
  703.  
  704.             col=(atoi(num));
  705.             attrib=col;
  706.             buildback(attrib, color);
  707.  
  708.             fmt_pos+=3;
  709.             strcat(formated, color);
  710.             pos+=strlen(color);
  711.           }
  712.           else
  713.           {
  714.             formated[pos]=buffer[fmt_pos];
  715.             formated[pos+1]=0;
  716.             ++pos;
  717.             ++fmt_pos;
  718.           }
  719.         }
  720.         else
  721.         {
  722.           formated[pos]=buffer[fmt_pos];
  723.           formated[pos+1]=0;
  724.           ++pos;
  725.           ++fmt_pos;
  726.         }
  727.       }
  728.       else
  729.       {
  730.         formated[pos]=buffer[fmt_pos];
  731.         formated[pos+1]=0;
  732.         ++pos;
  733.         ++fmt_pos;
  734.       }
  735.     }
  736.     else
  737.     {
  738.       formated[pos]=buffer[fmt_pos];
  739.       formated[pos+1]=0;
  740.       ++pos;
  741.       ++fmt_pos;
  742.     }
  743.   }
  744.   formated[pos]=0;
  745.   strcpy(buffer, formated);
  746.   free(formated);
  747. }
  748.  
  749. // Calls the above colorize_text to print out '|colors'
  750. // This call and npr_color are only meant for formats that when expanded
  751. // Will be less than 512 characters, this is fine for most cases, but not
  752. // something like an extended description
  753. void sprintf_color(char *buffer, char *fmt, ...)
  754. {
  755.   va_list ap;
  756.  
  757.   va_start(ap, fmt);
  758.   vsprintf(buffer, fmt, ap);
  759.   va_end(ap);
  760.  
  761.   colorize_text(buffer);
  762. }
  763.  
  764.  
  765.  
  766. void show_common_mods(void)
  767. {
  768.   existprint("COMMON.LST");
  769. }
  770.  
  771.  
  772. int replacefile(char *src, char *dst, int stats)
  773. {
  774.   if(exist(dst))
  775.     unlink(dst);
  776.  
  777.   return(copyfile(src, dst, stats));
  778. }
  779.  
  780.  
  781. int copyfile(char *src, char *dst, int stats)
  782. {
  783.   char source[201], dest[201];
  784.   char *cbuff;
  785.   int origfile, destfile;
  786.   int amount;
  787.  
  788.   char sys[201];
  789.  
  790.  
  791.   strcpy(source, src);
  792.   strcpy(dest, dst);
  793.  
  794.   strupr(source);
  795.   strupr(dest);
  796.  
  797.  
  798.   if(stats)
  799.   {
  800.     sprintf(sys, "8Copying File: 9%s - ", source);
  801.     outstr(sys);
  802.   }
  803.  
  804.  
  805.   if(exist(dest))
  806.     return 1;
  807.  
  808.   origfile=sh_open1(source,O_RDONLY | O_BINARY);
  809.  
  810.   sprintf(sys, "Copy Error: %s -> %s", source, dest);
  811.   if(origfile==-1)
  812.   {
  813.     nl();
  814.     ansic(3);
  815.     pl(sys);
  816.     sysoplog(sys);
  817.  
  818.     return 0;
  819.   }
  820.   destfile=sh_open1(dest,O_RDWR | O_BINARY | O_CREAT | O_TRUNC);
  821.   if(destfile==-1)
  822.   {
  823.     ansic(3);
  824.     pl(sys);
  825.     sysoplog(sys);
  826.  
  827.     sh_close(origfile);
  828.     return 0;
  829.   }
  830.  
  831.   else  /* copy file */
  832.   {
  833.     if((cbuff=(char *)malloca(25000))==NULL)
  834.     {
  835.       sysoplog("Could not allocate memory to copy file");
  836.       sh_close(origfile);
  837.       sh_close(destfile);
  838.       return 0;
  839.     }
  840.     else  // If this does not get executed, it was a failure
  841.     {
  842.       statusbarrec sb;
  843.       long fl;
  844.  
  845.       fl=filelength(origfile);
  846.  
  847.       if(stats)
  848.       {
  849.         sb.width=20;
  850.         sb.amount_per_square=4;
  851.         sb.square_list[0]='■';
  852.         sb.square_list[1]='░';
  853.         sb.square_list[2]='▒';
  854.         sb.square_list[3]='▓';
  855.         sb.empty_space='-';
  856.         sb.side_char1='[';
  857.         sb.side_char2=']';
  858.         sb.surround_color=WHITE;
  859.         sb.box_color=LIGHTBLUE;
  860.         sb.total_items=fl;
  861.         sb.current_item=0;
  862.  
  863.         statusbar(&sb);
  864.       }
  865.  
  866.       amount=sh_read(origfile, (void *)cbuff, 25000);
  867.  
  868.       if(stats)
  869.       {
  870.         sb.current_item+=amount;
  871.         statusbar(&sb);
  872.       }
  873.  
  874.       while(amount>0)
  875.       {
  876.         sh_write(destfile,(void *)cbuff,amount);
  877.  
  878.         amount=sh_read(origfile,(void *)cbuff,25000);
  879.  
  880.  
  881.         if(stats)
  882.         {
  883.           if(amount)
  884.           {
  885.             sb.current_item+=amount;
  886.             statusbar(&sb);
  887.           }
  888.         }
  889.       }
  890.  
  891.       sh_close(origfile);
  892.       sh_close(destfile);
  893.       farfree(cbuff);
  894.  
  895.       if(stats)
  896.       {
  897.         nl();
  898.         ansic(0);
  899.       }
  900.     }
  901.   }
  902.   return(2);
  903. }
  904.  
  905. // Just like copyfile, except if the files are on the same drive, it will
  906. // rename them (which is very fast) instead of copying them, also, after
  907. // a copy, it will remove the source file (since it was 'moved')
  908. int movefile(char *src, char *dst, int stats)
  909. {
  910.   char source[201], dest[201];
  911.   char *cbuff;
  912.   int origfile, destfile;
  913.   int x;
  914.  
  915.  
  916.   strcpy(source, src);
  917.   strcpy(dest, dst);
  918.  
  919.   strupr(source);
  920.   strupr(dest);
  921.  
  922.  
  923.   if ((strcmp(source,dest)!=0) && (exist(source)))
  924.   {
  925.     int which_way=0;
  926.     if ((source[1]!=':') && (dest[1]!=':'))
  927.       which_way=1;
  928.     if ((source[1]==':') && (dest[1]==':') && (source[0]==dest[0]))
  929.       which_way=1;
  930.  
  931.     if (which_way)
  932.     {
  933.       rename(source, dest);
  934.       return 2;
  935.     }
  936.   }
  937.  
  938.   x = copyfile(src, dst, stats);
  939.   unlink(src);
  940.  
  941.   return x;
  942. }
  943.  
  944.  
  945. char **alloc_2d(int row, int col, unsigned size)
  946. {
  947.    int i;
  948.    char **prow, *pdata;
  949.  
  950.    pdata = (char *) calloc(row * col, size);
  951.    if (pdata == (char *) NULL) {
  952.       sysoplog("No heap space for data\n");
  953.       pl("Memory Error!");
  954.       hangup=1;
  955.       return(NULL);
  956.    }
  957.    prow  = (char **) malloc(row * sizeof (char *));
  958.    if (prow == (char **) NULL) {
  959.       sysoplog("No heap space for row pointers\n");
  960.       pl("Memory Error!");
  961.       hangup=1;
  962.       free(pdata);
  963.       return(NULL);
  964.    }
  965.  
  966.    for (i = 0; i < row; i++) {
  967.      prow[i] = pdata;             /* store pointers to rows */
  968.      pdata += size * col;         /* move to next row */
  969.    }
  970.    return prow;                   /* pointer to 2D array */
  971. }
  972.  
  973. void free_2d(char **pa)
  974. {
  975.    free(*pa);                    /* free the data */
  976.    free(pa);                     /* free pointer to row pointers */
  977. }
  978.  
  979.  
  980.  
  981. varimenurec * addvarimenu(varimenurec *current, varimenurec *newitem)
  982. {
  983.   varimenurec *temp;
  984.   int cur, amount;
  985.  
  986.   if(current==NULL)
  987.   {
  988.     current=(varimenurec *) malloc(sizeof(varimenurec));
  989.     memmove((void *)current, (void *)newitem, sizeof(varimenurec));
  990.  
  991.     current->next=NULL;
  992.     current->amount=1;
  993.  
  994.     return(current);
  995.   }
  996.  
  997.  
  998.   amount=current->amount;
  999.   cur=0;
  1000.   temp=current;
  1001.  
  1002.   while(cur<amount-1)
  1003.   {
  1004.     temp=temp->next;
  1005.     ++cur;
  1006.   }
  1007.  
  1008.   temp->next=(varimenurec *) malloc(sizeof(varimenurec));
  1009.   temp=temp->next;
  1010.  
  1011.   memmove((void *)temp, (void *)newitem, sizeof(varimenurec));
  1012.   temp->next=NULL;
  1013.  
  1014.   ++current->amount;
  1015.   return(current);
  1016. }
  1017.  
  1018. void varimenuforward(varimenurec *menu, varimenuinfo *info)
  1019. {
  1020.   varimenurec *temp;
  1021.   int done=0, cur=0, amount=menu->amount;
  1022.  
  1023.   info->last=info->pos;
  1024.  
  1025.   while(!done)
  1026.   {
  1027.     if(info->pos)
  1028.     {
  1029.       --info->pos;
  1030.       temp=getvarimenurec(menu, info->pos);
  1031.       if(temp->active)
  1032.       {
  1033.         done=1;
  1034.         redrawvarimenu(COMMON_PARTIAL, menu, info);
  1035.       }
  1036.     }
  1037.     else
  1038.     {
  1039.       info->pos=amount-1;
  1040.  
  1041.       temp=getvarimenurec(menu, info->pos);
  1042.       if(temp->active)
  1043.       {
  1044.         done=1;
  1045.         redrawvarimenu(COMMON_PARTIAL, menu, info);
  1046.       }
  1047.     }
  1048.  
  1049.     ++cur;
  1050.  
  1051.     if(cur==amount)
  1052.       done=1;
  1053.   }
  1054. }
  1055.  
  1056. void varimenubackward(varimenurec *menu, varimenuinfo *info)
  1057. {
  1058.   varimenurec *temp;
  1059.   int done=0, cur=0, amount=menu->amount;
  1060.  
  1061.   info->last=info->pos;
  1062.  
  1063.   while(!done)
  1064.   {
  1065.     if(info->pos<amount-1)
  1066.     {
  1067.       ++info->pos;
  1068.  
  1069.       temp=getvarimenurec(menu, info->pos);
  1070.       if(temp->active)
  1071.       {
  1072.         done=1;
  1073.         redrawvarimenu(COMMON_PARTIAL, menu, info);
  1074.       }
  1075.     }
  1076.     else
  1077.     {
  1078.       info->pos=0;
  1079.  
  1080.       temp=getvarimenurec(menu, info->pos);
  1081.       if(temp->active)
  1082.       {
  1083.         done=1;
  1084.         redrawvarimenu(COMMON_PARTIAL, menu, info);
  1085.       }
  1086.     }
  1087.     ++cur;
  1088.  
  1089.     if(cur==amount)
  1090.       done=1;
  1091.   }
  1092. }
  1093.  
  1094. void varimenuleft(varimenurec *menu, varimenuinfo *info)
  1095. {
  1096.   varimenurec *temp;
  1097.   int done=0, cur=0, amount=menu->amount;
  1098.   int looky=0;
  1099.  
  1100.   info->last=info->pos;
  1101.  
  1102.   temp=getvarimenurec(menu, info->pos);
  1103.   looky=temp->ypos;
  1104.  
  1105.  
  1106.   while(!done)
  1107.   {
  1108.     int thisy=0;
  1109.  
  1110.     if(info->pos)
  1111.     {
  1112.       --info->pos;
  1113.       temp=getvarimenurec(menu, info->pos);
  1114.  
  1115.       thisy=temp->ypos;
  1116.  
  1117.       if(thisy==looky && temp->active)
  1118.       {
  1119.         done=1;
  1120.         redrawvarimenu(COMMON_PARTIAL, menu, info);
  1121.       }
  1122.     }
  1123.     else
  1124.     {
  1125.       if(looky)
  1126.         --looky;
  1127.       else
  1128.         looky=60;
  1129.  
  1130.       info->pos=amount-1;
  1131.  
  1132.       temp=getvarimenurec(menu, info->pos);
  1133.       thisy=temp->ypos;
  1134.  
  1135.       if(thisy==looky && temp->active)
  1136.       {
  1137.         done=1;
  1138.         redrawvarimenu(COMMON_PARTIAL, menu, info);
  1139.       }
  1140.     }
  1141.  
  1142.     ++cur;
  1143.  
  1144. //    if(cur==amount)
  1145. //      done=1;
  1146.   }
  1147.   
  1148. }
  1149.  
  1150. void varimenuup(varimenurec *menu, varimenuinfo *info)
  1151. {
  1152.   varimenurec *temp;
  1153.   int done=0, cur=0, amount=menu->amount;
  1154.   int lookx=0;
  1155.  
  1156.   info->last=info->pos;
  1157.  
  1158.   temp=getvarimenurec(menu, info->pos);
  1159.   lookx=temp->xpos;
  1160.  
  1161.  
  1162.   while(!done)
  1163.   {
  1164.     int thisx=0;
  1165.  
  1166.     if(info->pos)
  1167.     {
  1168.       --info->pos;
  1169.       temp=getvarimenurec(menu, info->pos);
  1170.       thisx=temp->xpos;
  1171.  
  1172.       if(thisx==lookx && temp->active)
  1173.       {
  1174.         done=1;
  1175.         redrawvarimenu(COMMON_PARTIAL, menu, info);
  1176.       }
  1177.     }
  1178.     else
  1179.     {
  1180.       if(lookx)
  1181.         --lookx;
  1182.       else
  1183.         lookx=80;
  1184.  
  1185.  
  1186.  
  1187.       info->pos=amount-1;
  1188.  
  1189.       temp=getvarimenurec(menu, info->pos);
  1190.       thisx=temp->xpos;
  1191.  
  1192.       if(thisx==lookx && temp->active)
  1193.       {
  1194.         done=1;
  1195.         redrawvarimenu(COMMON_PARTIAL, menu, info);
  1196.       }
  1197.     }
  1198.  
  1199.     ++cur;
  1200.  
  1201. //    if(cur==amount)
  1202. //      done=1;
  1203.   }
  1204.   
  1205. }
  1206.  
  1207. void varimenuright(varimenurec *menu, varimenuinfo *info)
  1208. {
  1209.   varimenurec *temp;
  1210.   int done=0, cur=0, amount=menu->amount;
  1211.   int looky;
  1212.  
  1213.   info->last=info->pos;
  1214.  
  1215.   temp=getvarimenurec(menu, info->pos);
  1216.   looky=temp->ypos;
  1217.  
  1218.  
  1219.   while(!done)
  1220.   {
  1221.     int thisy;
  1222.  
  1223.     if(info->pos<amount-1)
  1224.     {
  1225.       ++info->pos;
  1226.  
  1227.       temp=getvarimenurec(menu, info->pos);
  1228.       thisy=temp->ypos;
  1229.  
  1230.       if(thisy==looky && temp->active)
  1231.       {
  1232.         done=1;
  1233.         redrawvarimenu(COMMON_PARTIAL, menu, info);
  1234.       }
  1235.     }
  1236.     else
  1237.     {
  1238.       if(looky<=60)
  1239.         ++looky;
  1240.       else
  1241.         looky=0;
  1242.  
  1243.  
  1244.       info->pos=0;
  1245.  
  1246.       temp=getvarimenurec(menu, info->pos);
  1247.       thisy=temp->ypos;
  1248.  
  1249.       if(thisy==looky && temp->active)
  1250.       {
  1251.         done=1;
  1252.         redrawvarimenu(COMMON_PARTIAL, menu, info);
  1253.       }
  1254.     }
  1255.     ++cur;
  1256.  
  1257. //    if(cur==amount)
  1258. //      done=1;
  1259.   }
  1260. }
  1261.  
  1262. void varimenudown(varimenurec *menu, varimenuinfo *info)
  1263. {
  1264.   varimenurec *temp;
  1265.   int done=0, cur=0, amount=menu->amount;
  1266.   int lookx;
  1267.  
  1268.   info->last=info->pos;
  1269.  
  1270.   temp=getvarimenurec(menu, info->pos);
  1271.   lookx=temp->xpos;
  1272.  
  1273.  
  1274.   while(!done)
  1275.   {
  1276.     int thisx;
  1277.  
  1278.     if(info->pos<amount-1)
  1279.     {
  1280.       ++info->pos;
  1281.  
  1282.       temp=getvarimenurec(menu, info->pos);
  1283.       thisx=temp->xpos;
  1284.  
  1285.       if(thisx==lookx && temp->active)
  1286.       {
  1287.         done=1;
  1288.         redrawvarimenu(COMMON_PARTIAL, menu, info);
  1289.       }
  1290.     }
  1291.     else
  1292.     {
  1293.       if(lookx<120)
  1294.         ++lookx;
  1295.       else
  1296.         lookx=0;
  1297.  
  1298.  
  1299.  
  1300.       info->pos=0;
  1301.  
  1302.       temp=getvarimenurec(menu, info->pos);
  1303.       thisx=temp->xpos;
  1304.  
  1305.       if(thisx==lookx && temp->active)
  1306.       {
  1307.         done=1;
  1308.         redrawvarimenu(COMMON_PARTIAL, menu, info);
  1309.       }
  1310.     }
  1311.     ++cur;
  1312.  
  1313. //    if(cur==amount)
  1314. //      done=1;
  1315.   }
  1316. }
  1317.  
  1318.  
  1319. void varimenu(varimenurec *menu, varimenuinfo *info)
  1320. {
  1321.   varimenurec *temp;
  1322.  
  1323.  
  1324.   if(info->redraw!=COMMON_NONE)
  1325.     redrawvarimenu(info->redraw, menu, info);
  1326.  
  1327.   info->redraw=COMMON_NONE;
  1328.  
  1329.   while(1)
  1330.   {
  1331.     temp=getvarimenurec(menu, info->pos);
  1332.     switch(temp->type)
  1333.     {
  1334.       case SHOW_TEXT_TYPE:
  1335.         showtext(&temp->types->st, info);
  1336.         break;
  1337.  
  1338.       case INPUT_EDIT_TYPE:
  1339.         input_edit(&temp->types->ie, info);
  1340.         break;
  1341.  
  1342.       case RADIO_BUTTON_TYPE:
  1343.         radio_button(&temp->types->rb, info);
  1344.         break;
  1345.  
  1346.       case CHECK_BOX_TYPE:
  1347.         check_box(&temp->types->cb, info);
  1348.         break;
  1349.  
  1350.  
  1351.       default:
  1352.         sysoplog("Undefined type in varimenu");
  1353.         break;
  1354.     }
  1355.  
  1356.     if(varimenu_findhotkey(menu, info) > -1000)
  1357.     {
  1358.       redrawvarimenu(COMMON_PARTIAL, menu, info);
  1359.  
  1360.       temp=getvarimenurec(menu, info->pos);
  1361.       info->returnvalue=temp->returnvalue;
  1362.  
  1363.       return;
  1364.     }
  1365.  
  1366.     switch(info->event)
  1367.     {
  1368.       case COMMAND_STAB:
  1369.         varimenuforward(menu, info);
  1370.         break;
  1371.  
  1372.       case COMMAND_UP:
  1373.         varimenuup(menu, info);
  1374.         break;
  1375.  
  1376.       case COMMAND_LEFT:
  1377.         varimenuleft(menu, info);
  1378.         break;
  1379.  
  1380.       case COMMAND_DOWN:
  1381.         varimenudown(menu, info);
  1382.         break;
  1383.  
  1384.       case COMMAND_RIGHT:
  1385.         varimenuright(menu, info);
  1386.         break;
  1387.  
  1388.       case TAB:
  1389.         varimenubackward(menu, info);
  1390.         break;
  1391.  
  1392.       default:
  1393.  
  1394.         temp=getvarimenurec(menu, info->pos);
  1395.         info->returnvalue=temp->returnvalue;
  1396.         return;
  1397.     }
  1398.   }
  1399. }
  1400.  
  1401. varimenurec * getvarimenurec(varimenurec *menu, int which)
  1402. {
  1403.   varimenurec *temp;
  1404.   int pos=0;
  1405.   int amount=menu->amount;
  1406.  
  1407.   if(which>=amount)
  1408.   {
  1409.     sysoplog("Tried to get a varimenuitem that is out of range");
  1410.     return NULL;
  1411.   }
  1412.  
  1413.   temp=menu;
  1414.   if(which==0)
  1415.     return(temp);
  1416.  
  1417.  
  1418.  
  1419.   while(pos<which)
  1420.   {
  1421.     temp=temp->next;
  1422.     if(pos==which)
  1423.       return(temp);
  1424.  
  1425.     ++pos;
  1426.   }
  1427.  
  1428.   return(temp);
  1429. }
  1430.  
  1431.  
  1432.  
  1433.  
  1434. void redrawvarimenu(int redraw, varimenurec *menu, varimenuinfo *info)
  1435. {
  1436.   varimenurec *temp;
  1437.   int cur, savecolor=curatr;
  1438.   int mode;
  1439.  
  1440.  
  1441.  
  1442.   if(redraw==COMMON_FULL)
  1443.   {
  1444.     cur=0;
  1445.     temp=menu;
  1446.  
  1447.     setc(info->mi_normal);
  1448.  
  1449.  
  1450.     while(cur<menu->amount)
  1451.     {
  1452.       if(cur)
  1453.         temp=temp->next;
  1454.       else
  1455.         temp=menu;
  1456.  
  1457.       mode = temp->active==FALSE ? COMMON_INACTIVE : cur==info->pos ? COMMON_CURRENT : COMMON_ITEM;
  1458.  
  1459.  
  1460.       switch(temp->type)
  1461.       {
  1462.         case SHOW_TEXT_TYPE:
  1463.           redrawshowtext(COMMON_FULL, &temp->types->st, info, mode);
  1464.           break;
  1465.  
  1466.         case INPUT_EDIT_TYPE:
  1467.           redrawinputedit(COMMON_FULL, &temp->types->ie, info, mode);
  1468.           break;
  1469.  
  1470.         case RADIO_BUTTON_TYPE:
  1471.           redrawradiobutton(COMMON_FULL, &temp->types->rb, info, mode);
  1472.           break;
  1473.  
  1474.         case CHECK_BOX_TYPE:
  1475.           redrawcheckbox(COMMON_FULL, &temp->types->cb, info, mode);
  1476.           break;
  1477.  
  1478.         default:
  1479.           sysoplog("Undefined type in redrawvarimenu");
  1480.           break;
  1481.       }
  1482.  
  1483.       ++cur;
  1484.     }
  1485.   }
  1486.   else if(redraw==COMMON_PARTIAL)
  1487.   {
  1488.     if(info->pos!=info->last)
  1489.     {
  1490.       temp=getvarimenurec(menu, info->pos);
  1491.  
  1492.       mode = temp->active==FALSE ? COMMON_INACTIVE : COMMON_CURRENT;
  1493.  
  1494.       switch(temp->type)
  1495.       {
  1496.         case SHOW_TEXT_TYPE:
  1497.           redrawshowtext(COMMON_NONE, &temp->types->st, info, mode);
  1498.           break;
  1499.  
  1500.         case INPUT_EDIT_TYPE:
  1501.           redrawinputedit(COMMON_NONE, &temp->types->ie, info, mode);
  1502.           break;
  1503.  
  1504.         case RADIO_BUTTON_TYPE:
  1505.           redrawradiobutton(COMMON_NONE, &temp->types->rb, info, mode);
  1506.           break;
  1507.  
  1508.         case CHECK_BOX_TYPE:
  1509.           redrawcheckbox(COMMON_NONE, &temp->types->cb, info, mode);
  1510.           break;
  1511.  
  1512.  
  1513.         default:
  1514.           sysoplog("Undefined type in redrawvarimenu");
  1515.           break;
  1516.       }
  1517.  
  1518.  
  1519.  
  1520.       temp=getvarimenurec(menu, info->last);
  1521.  
  1522.       mode = temp->active==FALSE ? COMMON_INACTIVE : COMMON_ITEM;
  1523.  
  1524.       switch(temp->type)
  1525.       {
  1526.         case SHOW_TEXT_TYPE:
  1527.           redrawshowtext(COMMON_FULL, &temp->types->st, info, mode);
  1528.           break;
  1529.  
  1530.         case INPUT_EDIT_TYPE:
  1531.           redrawinputedit(COMMON_FULL, &temp->types->ie, info, mode);
  1532.           break;
  1533.  
  1534.         case RADIO_BUTTON_TYPE:
  1535.           redrawradiobutton(COMMON_FULL, &temp->types->rb, info, mode);
  1536.           break;
  1537.  
  1538.         case CHECK_BOX_TYPE:
  1539.           redrawcheckbox(COMMON_FULL, &temp->types->cb, info, mode);
  1540.           break;
  1541.  
  1542.  
  1543.         default:
  1544.           sysoplog("Undefined type in redrawvarimenu");
  1545.           break;
  1546.       }
  1547.     }
  1548.  
  1549.   }
  1550.   else if(redraw==COMMON_NONE)
  1551.   {
  1552.     return;
  1553.   }
  1554.   else
  1555.   {
  1556.     sysoplog("RedrawVariMenu is getting an invalid redraw value");
  1557.     return;
  1558.   }
  1559.  
  1560.   GOTO_XY(info->xpos, info->ypos);
  1561.   setc(savecolor);
  1562. }
  1563.  
  1564.  
  1565. void killvarimenu(varimenurec *menu)
  1566. {
  1567.   varimenurec *m[100];
  1568.   int cur=1, amount=menu->amount;
  1569.  
  1570.   m[0]=menu;
  1571.  
  1572.   while(cur < amount)
  1573.   {
  1574.     m[cur]=m[cur-1]->next;
  1575.     ++cur;
  1576.   }
  1577.  
  1578.   cur=0;
  1579.   while(cur < amount)
  1580.   {
  1581.     if(m[cur]->type==INPUT_EDIT_TYPE)
  1582.       kill_inputrec(&m[cur]->types->ie);
  1583.     else if(m[cur]->type==SHOW_TEXT_TYPE)
  1584.       kill_showtextrec(&m[cur]->types->st);
  1585.     else if(m[cur]->type==RADIO_BUTTON_TYPE)
  1586.       kill_radiobutton(&m[cur]->types->rb);
  1587.     else if(m[cur]->type==CHECK_BOX_TYPE)
  1588.       kill_checkbox(&m[cur]->types->cb);
  1589.  
  1590.  
  1591.  
  1592.     free(m[cur]);
  1593.     ++cur;
  1594.   }
  1595. }
  1596.  
  1597. void kill_inputrec(inputeditrec *input)
  1598. {
  1599.   free(input->text);
  1600.   free(input->show);
  1601. }
  1602.  
  1603. void kill_showtextrec(showtextrec *text)
  1604. {
  1605.   free(text->text);
  1606.   free(text->show);
  1607. }
  1608.  
  1609. void kill_radiobutton(radiobuttonrec *radio)
  1610. {
  1611.   if(radio!=radio)
  1612.     radio=radio;
  1613. }
  1614.  
  1615. void kill_checkbox(checkboxrec *check)
  1616. {
  1617.   if(check!=check)
  1618.     check=check;
  1619. }
  1620.  
  1621.  
  1622.  
  1623.  
  1624.  
  1625.  
  1626. int varimenu_findhotkey(varimenurec *menu, varimenuinfo *info)
  1627. {
  1628.   varimenurec *m;
  1629.   int cur=0, amount=menu->amount;
  1630.  
  1631.   unsigned e, h;
  1632.  
  1633.  
  1634.   m=menu;
  1635.  
  1636.   e=info->event;
  1637.   h=m->hotkey;
  1638.  
  1639.   if(!h || !e)
  1640.     return -1001;
  1641.  
  1642.   if(e>='A' && e <='Z')
  1643.     e=tolower(e);
  1644.   if(h>='A' && h <='Z')
  1645.     h=tolower(h);
  1646.  
  1647.   if(e==h && e)
  1648.   {
  1649.     if(menu->type==SHOW_TEXT_TYPE)
  1650.       info->event=EXECUTE;
  1651.     info->last=info->pos;
  1652.     info->pos=cur;
  1653.  
  1654.     return 1;
  1655.   }
  1656.  
  1657.   ++cur;  // we checked pos 0, inc up to pos 1
  1658.   while(cur < amount)
  1659.   {
  1660.     m=m->next;
  1661.  
  1662.     h=m->hotkey;
  1663.     if(h>='A' && h <='Z')
  1664.       h=tolower(h);
  1665.  
  1666.  
  1667.     if(e==h && e)
  1668.     {
  1669.       if(menu->type==SHOW_TEXT_TYPE)
  1670.         info->event=EXECUTE;
  1671.       info->last=info->pos;
  1672.       info->pos=cur;
  1673.  
  1674.       return 1;
  1675.     }
  1676.  
  1677.     ++cur;
  1678.  
  1679.   }
  1680.   return -1001;
  1681. }
  1682.  
  1683.  
  1684. void fillvarimenurec(varimenurec *menu, void *rec, int type, unsigned hotkey, int returnvalue, int active)
  1685. {
  1686.   memset(menu, 0, sizeof(varimenurec));
  1687.  
  1688.   (void *)menu->types=rec;
  1689.  
  1690.   menu->type=type;
  1691.  
  1692.   menu->hotkey=hotkey;
  1693.   menu->returnvalue=returnvalue;
  1694.  
  1695.   menu->active=active;
  1696.  
  1697.   switch(menu->type)
  1698.   {
  1699.     case SHOW_TEXT_TYPE:
  1700.       menu->xpos=menu->types->st.xpos;
  1701.       menu->ypos=menu->types->st.ypos;
  1702.       break;
  1703.  
  1704.     case INPUT_EDIT_TYPE:
  1705.       menu->xpos=menu->types->ie.xpos;
  1706.       menu->ypos=menu->types->ie.ypos;
  1707.       break;
  1708.  
  1709.     case RADIO_BUTTON_TYPE:
  1710.       menu->xpos=menu->types->rb.xpos;
  1711.       menu->ypos=menu->types->rb.ypos;
  1712.       break;
  1713.  
  1714.     case CHECK_BOX_TYPE:
  1715.       menu->xpos=menu->types->cb.xpos;
  1716.       menu->ypos=menu->types->cb.ypos;
  1717.       break;
  1718.   }
  1719. }
  1720.  
  1721.  
  1722.  
  1723. void build_inputrec(inputeditrec *input, int maxlen, int xpos, int ypos, int width, int insert, int char_case)
  1724. {
  1725.   memset(input, 0, sizeof(inputeditrec));
  1726.  
  1727.   input->pos=0;
  1728.   input->curlen=0;
  1729.   input->maxlen=maxlen;
  1730.   input->first=0;
  1731.   input->xpos=xpos;
  1732.   input->ypos=ypos;
  1733.   input->amount_to_show=width;
  1734.   input->curxpos=xpos;
  1735.   input->curypos=ypos;
  1736.   input->insert=insert;
  1737.   input->curmode=-1;
  1738.   input->text=(char *)malloc(maxlen+1);
  1739.   memset(input->text, 0, maxlen+1);
  1740.   input->show=(char *)malloc(width+5);
  1741.   memset(input->show, 0, width);
  1742.   input->char_case=char_case;
  1743. }
  1744.  
  1745. void build_radiobuttonrec(radiobuttonrec *radio, int xpos, int ypos, int amount, int pos, int rc, int fc)
  1746. {
  1747.   memset(radio, 0, sizeof(radiobuttonrec));
  1748.   radio->xpos=xpos;
  1749.   radio->ypos=ypos;
  1750.   radio->amount=amount;
  1751.   radio->pos=pos;
  1752.  
  1753.   if(pos >= amount)
  1754.     pos=amount-1;
  1755.  
  1756.   radio->radio_char=rc;
  1757.   radio->fill_char=fc;
  1758. }
  1759.  
  1760. void build_checkboxrec(checkboxrec *check, int xpos, int ypos, int amount, int pos, unsigned bi, int rc, int fc)
  1761. {
  1762.   memset(check, 0, sizeof(checkboxrec));
  1763.   check->xpos=xpos;
  1764.   check->ypos=ypos;
  1765.   check->amount=amount;
  1766.   check->bi.n.ni=bi;
  1767.  
  1768.   check->pos=pos;
  1769.   if(pos >= amount)
  1770.     pos=amount-1;
  1771.  
  1772.  
  1773.   check->check_char=rc;
  1774.   check->fill_char=fc;
  1775. }
  1776.  
  1777. void radio_button(radiobuttonrec *radio, varimenuinfo *info)
  1778. {
  1779.   if(info->redraw!=COMMON_NONE)
  1780.     redrawradiobutton(info->redraw, radio, info, COMMON_CURRENT);
  1781.  
  1782.   while(1)
  1783.   {
  1784.     info->event=get_kb_event();
  1785.  
  1786.     switch(info->event)
  1787.     {
  1788.       case COMMAND_UP:
  1789.         radio->last=radio->pos;
  1790.         if(radio->pos)
  1791.         {
  1792.           --radio->pos;
  1793.           redrawradiobutton(COMMON_PARTIAL, radio, info, COMMON_CURRENT);
  1794.         }
  1795.         else
  1796.         {
  1797.           radio->pos=radio->amount-1;
  1798.           redrawradiobutton(COMMON_PARTIAL, radio, info, COMMON_CURRENT);
  1799.         }
  1800.         info->event=0;
  1801.         return;
  1802.         
  1803.       case COMMAND_DOWN:
  1804.         radio->last=radio->pos;
  1805.         if(radio->pos<radio->amount-1)
  1806.         {
  1807.           ++radio->pos;
  1808.           redrawradiobutton(COMMON_PARTIAL, radio, info, COMMON_CURRENT);
  1809.         }
  1810.         else
  1811.         {
  1812.           radio->pos=0;
  1813.           redrawradiobutton(COMMON_PARTIAL, radio, info, COMMON_CURRENT);
  1814.         }
  1815.         info->event=0;
  1816.         return;
  1817.  
  1818.       default:
  1819.         return;
  1820.     }
  1821.   }
  1822. }
  1823.  
  1824. void check_box(checkboxrec *check, varimenuinfo *info)
  1825. {
  1826.   if(info->redraw!=COMMON_NONE)
  1827.     redrawcheckbox(info->redraw, check, info, COMMON_CURRENT);
  1828.  
  1829.   while(1)
  1830.   {
  1831.     info->event=get_kb_event();
  1832.  
  1833.     switch(info->event)
  1834.     {
  1835.       case COMMAND_UP:
  1836.         if(check->pos)
  1837.         {
  1838.           --check->pos;
  1839.           redrawcheckbox(COMMON_NONE, check, info, COMMON_CURRENT);
  1840.         }
  1841.         else
  1842.         {
  1843.           check->pos=check->amount-1;
  1844.           redrawcheckbox(COMMON_NONE, check, info, COMMON_CURRENT);
  1845.         }
  1846.         info->event=0;
  1847.         return;
  1848.         
  1849.       case COMMAND_DOWN:
  1850.         if(check->pos<check->amount-1)
  1851.         {
  1852.           ++check->pos;
  1853.           redrawcheckbox(COMMON_NONE, check, info, COMMON_CURRENT);
  1854.         }
  1855.         else
  1856.         {
  1857.           check->pos=0;
  1858.           redrawcheckbox(COMMON_NONE, check, info, COMMON_CURRENT);
  1859.         }
  1860.         info->event=0;
  1861.         return;
  1862.  
  1863.       case ' ':
  1864.         if(BitTst(check->bi.n.ni, check->pos))
  1865.           check->bi.n.ni=BitClr(check->bi.n.ni, check->pos);
  1866.         else
  1867.           check->bi.n.ni=BitSet(check->bi.n.ni, check->pos);
  1868.  
  1869.         redrawcheckbox(COMMON_PARTIAL, check, info, COMMON_CURRENT);
  1870.         info->event=0;
  1871.         return;
  1872.  
  1873.       default:
  1874.         return;
  1875.  
  1876.     }
  1877.   }
  1878. }
  1879.  
  1880.  
  1881.  
  1882. void input_edit(inputeditrec *input, varimenuinfo *info)
  1883. {
  1884.   if(info->redraw!=COMMON_NONE)
  1885.     redrawinputedit(info->redraw, input, info, COMMON_CURRENT);
  1886.  
  1887.   while(1)
  1888.   {
  1889.     info->event=get_kb_event();
  1890.     input->bs=FALSE;
  1891.  
  1892.     switch(info->event)
  1893.     {
  1894.       case COMMAND_LEFT:
  1895.         if(input->pos)
  1896.         {
  1897.           --input->pos;
  1898.           redrawinputedit(COMMON_PARTIAL, input, info, COMMON_CURRENT);
  1899.         }
  1900.         info->event=0;
  1901.         return;
  1902.         
  1903.       case COMMAND_RIGHT:
  1904.         if(input->pos<input->curlen)
  1905.         {
  1906.           ++input->pos;
  1907.           redrawinputedit(COMMON_PARTIAL, input, info, COMMON_CURRENT);
  1908.         }
  1909.         info->event=0;
  1910.         return;
  1911.  
  1912.       case COMMAND_HOME:
  1913.         if(input->pos!=0)
  1914.         {
  1915.           input->pos=0;
  1916.           redrawinputedit(COMMON_PARTIAL, input, info, COMMON_CURRENT);
  1917.         }
  1918.         info->event=0;
  1919.         return;
  1920.  
  1921.       case COMMAND_END:
  1922.         if(input->pos!=input->maxlen)
  1923.         {
  1924.           input->pos=input->curlen;
  1925.           redrawinputedit(COMMON_PARTIAL, input, info, COMMON_CURRENT);
  1926.         }
  1927.         info->event=0;
  1928.         return;
  1929.  
  1930.       case COMMAND_INSERT:
  1931.         input->insert=!input->insert;
  1932.         info->event=0;
  1933.         return;
  1934.  
  1935.       case BACKSPACE:
  1936.         if(input->pos)
  1937.         {
  1938.           --input->pos;
  1939.           delete_inputedit(input, info);
  1940.           redrawinputedit(COMMON_PARTIAL, input, info, COMMON_CURRENT);
  1941.         }
  1942.         info->event=0;
  1943.         return;
  1944.  
  1945.       case COMMAND_DELETE:
  1946.         delete_inputedit(input, info);
  1947.         redrawinputedit(COMMON_PARTIAL, input, info, COMMON_CURRENT);
  1948.         info->event=0;
  1949.         return;
  1950.  
  1951.       case COMMAND_STAB:
  1952.       case TAB:
  1953.         return;
  1954.  
  1955.       default:
  1956.  
  1957.         if(ok_char_inputedit(input, info))
  1958.         {
  1959.           if(IE_UPPER & input->char_case)
  1960.             info->event=toupper(info->event);
  1961.           else if(IE_PROPPER & input->char_case)
  1962.           {
  1963.             if(input->pos && isspace(input->text[input->pos-1]))
  1964.               info->event=toupper(info->event);
  1965.           }
  1966.  
  1967.           add_char_inputedit(input, info);
  1968.           redrawinputedit(COMMON_PARTIAL, input, info, COMMON_CURRENT);
  1969.  
  1970.           info->event=0;
  1971.           return;
  1972.         }
  1973.         else
  1974.           return;
  1975.     }
  1976.   }
  1977. }
  1978.  
  1979. int ok_char_inputedit(inputeditrec *input, varimenuinfo *info)
  1980. {
  1981.   unsigned event;
  1982.  
  1983.   event=info->event;
  1984.  
  1985.   if(event >= ' ' && event < 255)
  1986.     return 1;
  1987.  
  1988.   // Cut off warning until I expand this function
  1989.   if(input!=input)
  1990.     input=input;
  1991.  
  1992.   return 0;
  1993. }
  1994.  
  1995. void add_char_inputedit(inputeditrec *input, varimenuinfo *info)
  1996. {
  1997.   if(input->insert)
  1998.   {
  1999.     if(input->curlen<input->maxlen)
  2000.     {
  2001.       memmove(input->text+input->pos+1, input->text+input->pos, input->curlen-input->pos+1);
  2002.       input->text[input->pos]=(char)info->event;
  2003.       ++input->pos;
  2004.       ++input->curlen;
  2005.     }
  2006.   }
  2007.   else
  2008.   {
  2009.     if(input->pos<input->maxlen)
  2010.     {
  2011.       input->text[input->pos]=(char)info->event;
  2012.  
  2013.       if(input->pos==input->curlen)
  2014.         ++input->curlen;
  2015.  
  2016.       ++input->pos;
  2017.     }
  2018.   }
  2019. }
  2020.  
  2021.  
  2022. void redrawinputedit(int type, inputeditrec *input, varimenuinfo *info, int mode)
  2023. {
  2024.   int savecolor=curatr;
  2025.  
  2026.   if(input->pos < input->first)
  2027.   {
  2028.     input->first=input->pos - (input->amount_to_show/2);
  2029.     if(input->first<0)
  2030.       input->first=0;
  2031.  
  2032.     type=COMMON_FULL;
  2033.   }
  2034.   else if(input->pos - input->first > input->amount_to_show)
  2035.   {
  2036.     input->first=input->pos - (input->amount_to_show/2);
  2037.     if(input->first > input->maxlen)
  2038.       input->first=input->maxlen;
  2039.     type=COMMON_FULL;
  2040.   }
  2041.   else if(input->curmode!=mode)
  2042.     type=COMMON_FULL;
  2043.  
  2044.   input->curmode=mode;
  2045.  
  2046.   input->curxpos=input->xpos+(input->pos-input->first);
  2047.   input->curypos=input->ypos;
  2048.  
  2049.   if(type==COMMON_FULL)
  2050.   {
  2051.     strncpy(input->show, input->text+input->first, input->amount_to_show);
  2052.     input->show[input->amount_to_show]=0;
  2053.  
  2054.     pad_string(input->show, input->amount_to_show);
  2055.     GOTO_XY(input->xpos, input->ypos);
  2056.     setc(mode==COMMON_INACTIVE ? info->inactive_color : mode ==COMMON_ITEM ? info->mi_normal : info->ci_normal);
  2057.  
  2058.     if(IE_PASSWORD & input->char_case)
  2059.       echo=0;
  2060.     else
  2061.       echo=1;
  2062.     outstr(input->show);
  2063.   }
  2064.   else if(type==COMMON_PARTIAL)
  2065.   {
  2066.     int where = input->first+(input->pos-input->first);
  2067.     int a=input->amount_to_show-(input->pos-input->first)+1;
  2068.  
  2069.     if(input->pos!=input->first)
  2070.     {
  2071.       strncpy(input->show, input->text+where-1, a+1);
  2072.       input->show[a]=0;
  2073.       input->show[input->amount_to_show]=0 ;
  2074.  
  2075.       if(input->bs && strlen(input->show) != input->amount_to_show)
  2076.         strcat(input->show, " ");
  2077.  
  2078.       GOTO_XY(input->xpos + input->pos - input->first - 1, input->ypos);
  2079.     }
  2080.     else
  2081.     {
  2082.       strncpy(input->show, input->text+where, a);
  2083.       input->show[a]=0;
  2084.       input->show[input->amount_to_show]=0;
  2085.  
  2086.       if(input->bs && strlen(input->show) != input->amount_to_show)
  2087.         strcat(input->show, " ");
  2088.  
  2089.       GOTO_XY(input->xpos + input->pos - input->first, input->ypos);
  2090.     }
  2091.     setc(mode==COMMON_INACTIVE ? info->inactive_color : mode ==COMMON_ITEM ? info->mi_normal : info->ci_normal);
  2092.  
  2093.     if(IE_PASSWORD & input->char_case)
  2094.       echo=0;
  2095.     else
  2096.       echo=1;
  2097.     outstr(input->show);
  2098.   }
  2099.   else if(type==COMMON_NONE)
  2100.   {
  2101.   }
  2102.   else
  2103.   {
  2104.     sysoplog("Undefined update type in function redrawinputedit");
  2105.   }
  2106.  
  2107.  
  2108.   if(mode==COMMON_CURRENT)
  2109.   {
  2110.  
  2111.     info->xpos=input->xpos + input->pos - input->first;
  2112.     info->ypos=input->ypos;
  2113.     GOTO_XY(info->xpos, info->ypos);
  2114.   }
  2115.  
  2116.   input->bs=FALSE;
  2117.   setc(savecolor);
  2118. }
  2119.  
  2120.  
  2121. void delete_inputedit(inputeditrec *input, varimenuinfo *info)
  2122. {
  2123.   if((input->pos>0 && input->pos==input->curlen) || !input->curlen)
  2124.   {
  2125.     info->redraw=COMMON_NONE;
  2126.     return;
  2127.   }
  2128.  
  2129.   memmove(input->text+input->pos, input->text+input->pos+1, input->curlen-input->pos);
  2130.  
  2131.   --input->curlen;
  2132.   input->bs=TRUE;
  2133.   info->redraw=COMMON_PARTIAL;
  2134. }
  2135.  
  2136.  
  2137. void redrawradiobutton(int redraw, radiobuttonrec *radio, varimenuinfo *info, int mode)
  2138. {
  2139.   int savecolor=curatr;
  2140.   int color;
  2141.   int x=0;
  2142.  
  2143.   if(redraw==COMMON_FULL)
  2144.   {
  2145.  
  2146.     while(x<radio->amount)
  2147.     {
  2148.       color = (mode == COMMON_INACTIVE ? info->inactive_color : x == radio->pos ? info->mi_normal : info->ci_normal);
  2149.       setc(color);
  2150.  
  2151.       GOTO_XY(radio->xpos, radio->ypos+x);
  2152.       if(x==radio->pos)
  2153.         outchr(radio->radio_char);
  2154.       else
  2155.         outchr(radio->fill_char);
  2156.  
  2157.       ++x;
  2158.     }
  2159.   }
  2160.   else if(redraw!=COMMON_NONE)
  2161.   {
  2162.     if(radio->pos!=radio->last)
  2163.     {
  2164.       while(x<radio->amount)
  2165.       {
  2166.         if(x==radio->pos || x==radio->last)
  2167.         {
  2168.           color = (mode == COMMON_INACTIVE ? info->inactive_color : x == radio->pos ? info->mi_normal : info->ci_normal);
  2169.           setc(color);
  2170.  
  2171.           GOTO_XY(radio->xpos, radio->ypos+x);
  2172.           if(x==radio->pos)
  2173.             outchr(radio->radio_char);
  2174.           else
  2175.             outchr(radio->fill_char);
  2176.         }
  2177.         ++x;
  2178.       }
  2179.     }
  2180.   }
  2181.  
  2182.  
  2183.   if(mode==COMMON_CURRENT)
  2184.   {
  2185.     info->xpos=radio->xpos;
  2186.     info->ypos=radio->ypos+radio->pos;
  2187.     GOTO_XY(info->xpos, info->ypos);
  2188.   }
  2189.  
  2190.   setc(savecolor);
  2191. }
  2192.  
  2193. void redrawcheckbox(int redraw, checkboxrec *check, varimenuinfo *info, int mode)
  2194. {
  2195.   int savecolor=curatr;
  2196.   int color;
  2197.   int x=0;
  2198.  
  2199.   if(redraw==COMMON_FULL)
  2200.   {
  2201.  
  2202.     while(x<check->amount)
  2203.     {
  2204.       color = (mode == COMMON_INACTIVE ? info->inactive_color : x == check->pos ? info->mi_normal : info->ci_normal);
  2205.       setc(color);
  2206.  
  2207.       GOTO_XY(check->xpos, check->ypos+x);
  2208.       if(BitTst(check->bi.n.ni, x))
  2209.         outchr(check->check_char);
  2210.       else
  2211.         outchr(check->fill_char);
  2212.  
  2213.       ++x;
  2214.     }
  2215.   }
  2216.   else if(redraw!=COMMON_NONE)
  2217.   {
  2218.     while(x<check->amount)
  2219.     {
  2220.       if(x==check->pos)
  2221.       {
  2222.         color = (mode == COMMON_INACTIVE ? info->inactive_color : x == check->pos ? info->mi_normal : info->ci_normal);
  2223.         setc(color);
  2224.  
  2225.         GOTO_XY(check->xpos, check->ypos+x);
  2226.         if(BitTst(check->bi.n.ni, x))
  2227.           outchr(check->check_char);
  2228.         else
  2229.           outchr(check->fill_char);
  2230.       }
  2231.       ++x;
  2232.     }
  2233.   }
  2234.  
  2235.  
  2236.   if(mode==COMMON_CURRENT)
  2237.   {
  2238.     info->xpos=check->xpos;
  2239.     info->ypos=check->ypos+check->pos;
  2240.     GOTO_XY(info->xpos, info->ypos);
  2241.   }
  2242.  
  2243.   setc(savecolor);
  2244. }
  2245.  
  2246.  
  2247.  
  2248. void redrawshowtext(int redraw, showtextrec *text, varimenuinfo *info, int mode)
  2249. {
  2250.   int savecolor=curatr;
  2251.   int color;
  2252.  
  2253.   strncpy(text->show, text->text, text->amount_to_show);
  2254.   text->show[text->amount_to_show]=0;
  2255.  
  2256.   justify_string(text->show, text->amount_to_show, text->bg, text->justify);
  2257.  
  2258.   color = (mode == COMMON_INACTIVE ? info->inactive_color : mode == COMMON_ITEM ? info->mi_normal : info->ci_normal);
  2259.   if(color!=text->cur_color)
  2260.     redraw=COMMON_FULL;
  2261.   text->cur_color=color;
  2262.  
  2263.   if(redraw!=COMMON_NONE)
  2264.   {
  2265.     setc(color);
  2266.  
  2267.     GOTO_XY(text->xpos, text->ypos);
  2268.     outstr(text->show);
  2269.   }
  2270.  
  2271.   if(mode==COMMON_CURRENT)
  2272.   {
  2273.     info->xpos=text->xpos;
  2274.     info->ypos=text->ypos;
  2275.     GOTO_XY(info->xpos, info->ypos);
  2276.   }
  2277.  
  2278.   setc(savecolor);
  2279. }
  2280.  
  2281. void showtext(showtextrec *text, varimenuinfo *info)
  2282. {
  2283.  
  2284.   if(info->redraw!=COMMON_NONE)
  2285.     redrawshowtext(info->redraw, text, info, COMMON_CURRENT);
  2286.  
  2287.   info->event=get_kb_event();
  2288.   return;
  2289. }
  2290.  
  2291. void build_showtextrec(showtextrec *text, int xpos, int ypos, int width, char *t, int justify, int bg)
  2292. {
  2293.   memset(text, 0, sizeof(showtextrec));
  2294.  
  2295.   text->xpos=xpos;
  2296.   text->ypos=ypos;
  2297.   text->amount_to_show=width;
  2298.   text->curxpos=xpos;
  2299.   text->curypos=ypos;
  2300.  
  2301.   text->justify=justify;
  2302.   text->bg=bg;
  2303.  
  2304.   text->text=(char *)malloc(width+1);
  2305.   strncpy(text->text, t, width);
  2306.   text->text[width]=0;
  2307.  
  2308.   text->show=(char *)malloc(width+1);
  2309. }
  2310.  
  2311.  
  2312.  
  2313.  
  2314. #ifdef TEST_VM
  2315. void test_vm(void)
  2316. {
  2317.   inputeditrec input1, input2;
  2318.   showtextrec text1, text2;
  2319.  
  2320.   varimenurec *menu=NULL, newmenu;
  2321.   varimenuinfo info={YELLOW+(BLUE<<4), RED+(BLUE<<4), BLACK+(CYAN<<4), RED+(CYAN<<4), DARKGRAY+(BLUE<<4),
  2322.                      COMMON_FULL, 0, 0, 0, 0, 0};
  2323.   int done=0;
  2324.  
  2325.   enum TEST_STUFF
  2326.   {
  2327.     LOGON,
  2328.     CHAT,
  2329.     EMAIL,
  2330.     GOODBYE
  2331.   };
  2332.  
  2333.  
  2334.   build_showtextrec(&text1, 5, 5, 17, "Logon", JUSTIFY_CENTER, '■');
  2335.   fillvarimenurec(&newmenu, &text1, SHOW_TEXT_TYPE, 0, LOGON, COMMON_ACTIVE);
  2336.   menu=addvarimenu(menu, &newmenu);
  2337.  
  2338.   build_showtextrec(&text2, 5, 7, 17, "GoodBye", JUSTIFY_CENTER, '∙');
  2339.   fillvarimenurec(&newmenu, &text2, SHOW_TEXT_TYPE, 0, GOODBYE, COMMON_ACTIVE);
  2340.   menu=addvarimenu(menu, &newmenu);
  2341.  
  2342.   build_inputrec(&input1, 30, 5, 9, 17, 1, IE_MIXED);
  2343.   fillvarimenurec(&newmenu, &input1, INPUT_EDIT_TYPE, 0, CHAT, COMMON_ACTIVE);
  2344.   menu=addvarimenu(menu, &newmenu);
  2345.  
  2346.  
  2347.   build_inputrec(&input2, 30, 5, 11, 17, 1, IE_PROPPER);
  2348.   fillvarimenurec(&newmenu, &input2, INPUT_EDIT_TYPE, 0, EMAIL, COMMON_ACTIVE);
  2349.   menu=addvarimenu(menu, &newmenu);
  2350.  
  2351.  
  2352.   // Print out ansi or prep screen in other way
  2353.   CLS();
  2354.  
  2355.   while(!done && !hangup)
  2356.   {
  2357.     varimenu(menu, &info);
  2358.  
  2359.     switch(info.event)
  2360.     {
  2361.       case EXECUTE:
  2362.         switch(info.returnvalue)
  2363.         {
  2364.           case GOODBYE:
  2365.           case GET_OUT:
  2366.             done=1;
  2367.             break;
  2368.           default:
  2369.             info.redraw=COMMON_NONE;
  2370.             break;
  2371.         }
  2372.         break;
  2373.  
  2374.       case GET_OUT:
  2375.         done=1;
  2376.         break;
  2377.  
  2378.       default:
  2379.         info.redraw=COMMON_NONE;
  2380.         break;
  2381.     }
  2382.  
  2383.   }
  2384.  
  2385.   killvarimenu(menu);
  2386.   CLS();
  2387. }
  2388. #endif   // end ifdef test_var
  2389.  
  2390.  
  2391.  
  2392.  
  2393. // Waits amount of secs, or until a key is hit
  2394. void wait_sec_or_hit(double seconds)
  2395. {
  2396.   time_t time1;
  2397.   time_t time2;
  2398.  
  2399.   time(&time1);
  2400.   time(&time2);
  2401.  
  2402.   if( seconds == 1 )
  2403.     ++seconds;
  2404.  
  2405.   while(difftime(time2,time1) < seconds && !hangup && !comhit() && !kbhit())
  2406.     time(&time2);
  2407. }
  2408.  
  2409. // Waits for 'seconds' seconds, does not exit on comhit
  2410. void wait_sec(double seconds)
  2411. {
  2412.   time_t time1;
  2413.   time_t time2;
  2414.  
  2415.   time(&time1);
  2416.   time(&time2);
  2417.  
  2418.   if( seconds == 1 )
  2419.     ++seconds;
  2420.  
  2421.   while(difftime(time2,time1) < seconds && !hangup)
  2422.     time(&time2);
  2423. }
  2424.  
  2425.  
  2426. long filesize(FILE *stream)
  2427. {
  2428.   long curpos, length;
  2429.   
  2430.   curpos=ftell(stream);
  2431.   
  2432.   fseek(stream, 0L, SEEK_END);
  2433.   length=ftell(stream);
  2434.   
  2435.   fseek(stream, curpos, SEEK_SET);
  2436.   
  2437.   return length;
  2438. }
  2439.  
  2440.  
  2441.  
  2442. int fset_rec(FILE *stream, unsigned rec, unsigned rec_size)
  2443. {
  2444.   int error;
  2445.   
  2446.   error = fseek(stream, (long) ((rec)*((long)rec_size)), SEEK_SET);
  2447.  
  2448.   
  2449.   if(error)
  2450.     ; // Could not set rec
  2451.     
  2452.   return(!error);
  2453. }
  2454.  
  2455. int set_rec(int filenum, unsigned rec, unsigned rec_size)
  2456. {
  2457.   int error;
  2458.   
  2459.   error = sh_lseek(filenum, (long) ((rec)*((long)rec_size)), SEEK_SET);
  2460.  
  2461.   
  2462.   if(error)
  2463.     ; // Could not set rec
  2464.     
  2465.   return(!error);
  2466. }
  2467.  
  2468.  
  2469.  
  2470. // #define check_ar(which) check_bitfield(thisuser.ar, (which))
  2471. // #define check_dar(which) check_bitfield(thisuser.dar, (which))
  2472. // These are defined in COMMON.H, example calls:
  2473. //
  2474. // if(check_ar("CDF"))  (or if(check_dar("GA"))
  2475. //   do_whatever();
  2476. //
  2477. // It will return TRUE (1) if all bits specified in paremater 'which' are set
  2478. // Say in check_ar("CDF"), if the user has CD, but not F specified, then FALSE
  2479. // (0) is returned/
  2480. //
  2481. // To use check_bitfield, you must specify the bitfield you are checking, and
  2482. // you must specify bit 'A' as the first bit, 'B' as the second... on up to 'P'
  2483. // as your 16th bit, and paremater 'which' is used just as above
  2484. //
  2485. // if(check_bitfield(thisuser.restrict, "AC"))
  2486. //   annoy_user_a_little();
  2487. //
  2488. // Should make checking bit fields for novice users, as well as everyone else
  2489. // alot easier
  2490.  
  2491. int check_bitfield(unsigned bitfield, char *which)
  2492. {
  2493.   unsigned total=0, bit, temp;
  2494.   int x=0, y;
  2495.  
  2496.   strupr(which);
  2497.  
  2498.   while((y=which[x])!=0)
  2499.   {
  2500.     // There IS error detection for if you specify the same bit field
  2501.     // twice, or if you specify something other than A-P
  2502.     if(y>='A' && y <= 'P')
  2503.     {
  2504.       bit=1 << (y-'A');
  2505.       // Make sure that this bit has not already been set
  2506.       if(!(total&bit))
  2507.         total+=bit;
  2508.     }
  2509.     ++x;
  2510.   }
  2511.  
  2512.   temp=bitfield & total;
  2513.   if(temp==total)
  2514.     return 1;
  2515.   return 0;
  2516. }
  2517.  
  2518.  
  2519. #ifdef TEST_BITFIELD
  2520. void test_check_bitfield(void)
  2521. {
  2522.   int done=0;
  2523.   char s[17];
  2524.  
  2525.   while(!done)
  2526.   {
  2527.     pl("Enter alpha style bit field to check against thisuser.ar");
  2528.     input(s, 16);
  2529.  
  2530.     if(s[0])
  2531.     {
  2532.       if(check_ar(s))
  2533.         pl("You have the specified bits");
  2534.       else
  2535.         pl("You DON'T have the specified bits");
  2536.     }
  2537.     else
  2538.       done=1;
  2539.   }
  2540. }
  2541. #endif
  2542.  
  2543.  
  2544. int check_arc(char *filename)
  2545. {
  2546.   char header[10];
  2547.   char *ext;
  2548.   int file;
  2549.  
  2550.  
  2551.   file=sh_open1(filename, O_RDONLY);
  2552.  
  2553.   if(file<0)
  2554.     return(COMPRESSION_UNKNOWN);
  2555.  
  2556.   sh_lseek(file, 0, SEEK_SET);
  2557.   sh_read(file, (void *)&header, 10);
  2558.  
  2559.   sh_close(file);
  2560.  
  2561.   switch(header[0])
  2562.   {
  2563.     case 0x60:
  2564.       if((unsigned char)header[2]==(unsigned char)0xEA)
  2565.         return(COMPRESSION_ARJ);
  2566.  
  2567.       break;
  2568.  
  2569.     case 0x1a:
  2570.       return(COMPRESSION_PAK);
  2571.  
  2572.     case 'P':
  2573.       if(header[1]=='K')
  2574.         return(COMPRESSION_ZIP);
  2575.  
  2576.       break;
  2577.  
  2578.     case 'Z':
  2579.       if(header[1]== 'O' && header[2] == 'O')
  2580.         return(COMPRESSION_ZOO);
  2581.  
  2582.       break;
  2583.  
  2584.     default:
  2585.  
  2586.       if(strstr(header, "-lh"))
  2587.         return(COMPRESSION_LHA);
  2588.  
  2589.       // Guess on type, using extension to guess
  2590.       ext=strstr(filename, ".");
  2591.  
  2592.       if(ext)
  2593.       {
  2594.         ++ext;
  2595.  
  2596.         if(stricmp(ext, "ZIP")==0)
  2597.           return(COMPRESSION_ZIP);
  2598.  
  2599.         if(stricmp(ext, "LHA")==0)
  2600.           return(COMPRESSION_LHA);
  2601.  
  2602.         if(stricmp(ext, "LZH")==0)
  2603.           return(COMPRESSION_LHA);
  2604.  
  2605.         if(stricmp(ext, "ZOO")==0)
  2606.           return(COMPRESSION_ZOO);
  2607.  
  2608.         if(stricmp(ext, "ARC")==0)
  2609.           return(COMPRESSION_PAK);
  2610.  
  2611.         if(stricmp(ext, "PAK")==0)
  2612.           return(COMPRESSION_PAK);
  2613.  
  2614.         if(stricmp(ext, "ARJ")==0)
  2615.           return(COMPRESSION_ARJ);
  2616.  
  2617.         return(COMPRESSION_UNKNOWN);
  2618.       }
  2619.   }
  2620.   return(COMPRESSION_UNKNOWN);
  2621. }
  2622.  
  2623. // Returns which archive as a number in your archive config
  2624. // Returns the first archiver you have listed if unknown
  2625. // One thing to note, if an 'arc' is found, it uses pak, and returns that
  2626. // The reason being, PAK does all ARC does, plus a little more, I belive
  2627. // PAK has its own special modes, but still look like an ARC, thus, an ARC
  2628. // Will puke if it sees this
  2629. int match_archiver(char *filename)
  2630. {
  2631.   int x=0;
  2632.   char type[4];
  2633.  
  2634.   x=check_arc(filename);
  2635.  
  2636.   if(x==COMPRESSION_UNKNOWN)
  2637.     return 0;
  2638.  
  2639.  
  2640.   switch(x)
  2641.   {
  2642.     case COMPRESSION_ZIP:
  2643.       strcpy(type, "ZIP");
  2644.       break;
  2645.  
  2646.     case COMPRESSION_LHA:
  2647.       strcpy(type, "LHA");
  2648.       break;
  2649.  
  2650.     case COMPRESSION_ARJ:
  2651.       strcpy(type, "ARJ");
  2652.       break;
  2653.  
  2654.     case COMPRESSION_PAK:
  2655.       strcpy(type, "PAK");
  2656.       break;
  2657.  
  2658.     case COMPRESSION_ZOO:
  2659.       strcpy(type, "ZOO");
  2660.       break;
  2661.   }
  2662.  
  2663.   x=0;
  2664.  
  2665.   while(x<4)
  2666.   {
  2667.     if(stricmp(type, syscfg.arcs[x].extension)==0)
  2668.       return x;
  2669.  
  2670.     ++x;
  2671.   }
  2672.  
  2673.   return 0;
  2674. }
  2675.  
  2676.  
  2677.  
  2678. long file_daten(char *filename)
  2679. {
  2680.   int fn;
  2681.  
  2682.   struct ftime file;
  2683.   struct time  dtime;
  2684.   struct date  ddate;
  2685.  
  2686.  
  2687.   fn = sh_open1(filename, O_RDONLY);
  2688.   if (fn != -1)
  2689.   {
  2690.     getftime(fn, &file);
  2691.     fn=sh_close(fn);
  2692.  
  2693.     dtime.ti_hund = 0;
  2694.     dtime.ti_min = file.ft_min;
  2695.     dtime.ti_hour = file.ft_hour;
  2696.     dtime.ti_sec = file.ft_tsec * 2;
  2697.     ddate.da_year = file.ft_year + 1980;
  2698.     ddate.da_day = file.ft_day;
  2699.     ddate.da_mon = file.ft_month;
  2700.  
  2701.     return(dostounix(&ddate, &dtime));
  2702.   }
  2703.   return 0;
  2704. }
  2705.  
  2706.  
  2707.  
  2708.  
  2709. void build_inputpicrec(inputpicrec *input, int xpos, int ypos, int width, int insert, char *picture)
  2710. {
  2711.   memset(input, 0, sizeof(inputpicrec));
  2712.  
  2713.   input->pos=0;
  2714.   input->curlen=0;
  2715.   input->first=0;
  2716.   input->xpos=xpos;
  2717.   input->ypos=ypos;
  2718.   input->amount_to_show=width;
  2719.   input->curxpos=xpos;
  2720.   input->curypos=ypos;
  2721.   input->insert=insert;
  2722.   input->curmode=-1;
  2723.   input->show=(char *)malloc(width+5);
  2724.   memset(input->show, 0, width);
  2725. //  input->picture=get_picture(picture, input->maxlen);
  2726.   if(picture!=picture)
  2727.     picture=picture;
  2728.   input->text=(char *)malloc(input->maxlen+1);
  2729.   memset(input->text, ' ', input->maxlen+1);
  2730.  
  2731. }
  2732.  
  2733. void kill_inputpic(inputpicrec *input)
  2734. {
  2735.   free(input->text);
  2736.   free(input->show);
  2737.  
  2738.   if(input->picture)
  2739.     free(input->picture);
  2740. }
  2741.  
  2742. void input_picture(inputpicrec *input, varimenuinfo *info)
  2743. {
  2744.   if(info->redraw!=COMMON_NONE)
  2745.     redrawinputpic(info->redraw, input, info, COMMON_CURRENT);
  2746.  
  2747.   while(1)
  2748.   {
  2749.     info->event=get_kb_event();
  2750.     input->bs=FALSE;
  2751.  
  2752.     switch(info->event)
  2753.     {
  2754.       case COMMAND_LEFT:
  2755.         if(input->pos)
  2756.         {
  2757.           --input->pos;
  2758.           redrawinputpic(COMMON_PARTIAL, input, info, COMMON_CURRENT);
  2759.         }
  2760.         info->event=0;
  2761.         return;
  2762.         
  2763.       case COMMAND_RIGHT:
  2764.         if(input->pos<input->curlen)
  2765.         {
  2766.           ++input->pos;
  2767.           redrawinputpic(COMMON_PARTIAL, input, info, COMMON_CURRENT);
  2768.         }
  2769.         info->event=0;
  2770.         return;
  2771.  
  2772.       case COMMAND_HOME:
  2773.         if(input->pos!=0)
  2774.         {
  2775.           input->pos=0;
  2776.           redrawinputpic(COMMON_PARTIAL, input, info, COMMON_CURRENT);
  2777.         }
  2778.         info->event=0;
  2779.         return;
  2780.  
  2781.       case COMMAND_END:
  2782.         if(input->pos!=input->maxlen)
  2783.         {
  2784.           input->pos=input->curlen;
  2785.           redrawinputpic(COMMON_PARTIAL, input, info, COMMON_CURRENT);
  2786.         }
  2787.         info->event=0;
  2788.         return;
  2789.  
  2790.       case BACKSPACE:
  2791.         if(input->pos)
  2792.         {
  2793.           --input->pos;
  2794.           input->text[input->pos]=' ';
  2795.           redrawinputpic(COMMON_PARTIAL, input, info, COMMON_CURRENT);
  2796.         }
  2797.         info->event=0;
  2798.         return;
  2799.  
  2800.       case COMMAND_DELETE:
  2801.         input->text[input->pos]=' ';
  2802.         redrawinputpic(COMMON_PARTIAL, input, info, COMMON_CURRENT);
  2803.         info->event=0;
  2804.         return;
  2805.  
  2806.       case COMMAND_STAB:
  2807.       case TAB:
  2808.         return;
  2809.  
  2810.       default:
  2811.  
  2812.         if(ok_char_inputpic(input, info))
  2813.         {
  2814.           input->text[input->pos]=info->event;
  2815.           ++info->pos;
  2816.           redrawinputpic(COMMON_PARTIAL, input, info, COMMON_CURRENT);
  2817.  
  2818.           info->event=0;
  2819.           return;
  2820.         }
  2821.         else
  2822.           return;
  2823.     }
  2824.   }
  2825. }
  2826.  
  2827. int ok_char_inputpic(inputpicrec *input, varimenuinfo *info)
  2828. {
  2829.   unsigned event;
  2830.  
  2831.   event=info->event;
  2832.  
  2833.   if(event >= ' ' && event < 255)
  2834.     return 1;
  2835.  
  2836.   // Cut off warning until I expand this function
  2837.   if(input!=input)
  2838.     input=input;
  2839.  
  2840.   return 0;
  2841. }
  2842.  
  2843.  
  2844. char ** read_picture(char *picture)
  2845. {
  2846.   int amount;
  2847.   int pos=0;
  2848.   int x, done=0;
  2849.   int next=0;
  2850.  
  2851.  
  2852.   while(!done)
  2853.   {
  2854.  
  2855.     x=picture[pos];
  2856.  
  2857.     if(!x)
  2858.       break;
  2859.  
  2860.     switch(x)
  2861.     {
  2862.       case '!': // Execlude
  2863.         next=1;
  2864.         ++pos;
  2865.         break;
  2866.  
  2867.       case '[': // Start range
  2868.         while(x!=']' && x)
  2869.         {
  2870.           ++pos;
  2871.           x=picture[pos];
  2872.         }
  2873.         next=0;
  2874.         break;
  2875.  
  2876.       case '@': // Predefined type
  2877.         next=1;
  2878.         ++pos;
  2879.         break;
  2880.  
  2881.       case '~': // Force next char
  2882.         ++pos;
  2883.         if(picture[pos])
  2884.           ++pos;
  2885.  
  2886.         next=0;
  2887.         break;
  2888.  
  2889.       default:
  2890.         next=0;
  2891.         ++pos;
  2892.         break;
  2893.     }
  2894.  
  2895.     if(next)
  2896.       ++amount;
  2897.  
  2898.   }
  2899.  
  2900.   return NULL;
  2901. }
  2902.  
  2903.  
  2904.  
  2905.  
  2906.  
  2907.  
  2908. void redrawinputpic(int type, inputpicrec *input, varimenuinfo *info, int mode)
  2909. {
  2910.   int savecolor=curatr;
  2911.  
  2912.   if(input->pos < input->first)
  2913.   {
  2914.     input->first=input->pos - (input->amount_to_show/2);
  2915.     if(input->first<0)
  2916.       input->first=0;
  2917.  
  2918.     type=COMMON_FULL;
  2919.   }
  2920.   else if(input->pos - input->first > input->amount_to_show)
  2921.   {
  2922.     input->first=input->pos - (input->amount_to_show/2);
  2923.     if(input->first > input->maxlen)
  2924.       input->first=input->maxlen;
  2925.     type=COMMON_FULL;
  2926.   }
  2927.   else if(input->curmode!=mode)
  2928.     type=COMMON_FULL;
  2929.  
  2930.   input->curmode=mode;
  2931.  
  2932.   input->curxpos=input->xpos+(input->pos-input->first);
  2933.   input->curypos=input->ypos;
  2934.  
  2935.   if(type==COMMON_FULL)
  2936.   {
  2937.     strncpy(input->show, input->text+input->first, input->amount_to_show);
  2938.     input->show[input->amount_to_show]=0;
  2939.  
  2940.     pad_string(input->show, input->amount_to_show);
  2941.     GOTO_XY(input->xpos, input->ypos);
  2942.     setc(mode==COMMON_INACTIVE ? info->inactive_color : mode ==COMMON_ITEM ? info->mi_normal : info->ci_normal);
  2943.  
  2944.     if(IE_PASSWORD & input->char_case)
  2945.       echo=0;
  2946.     else
  2947.       echo=1;
  2948.     outstr(input->show);
  2949.   }
  2950.   else if(type==COMMON_PARTIAL)
  2951.   {
  2952.     int where = input->first+(input->pos-input->first);
  2953.     int a=input->amount_to_show-(input->pos-input->first)+1;
  2954.  
  2955.     if(input->pos!=input->first)
  2956.     {
  2957.       strncpy(input->show, input->text+where-1, a+1);
  2958.       input->show[a]=0;
  2959.       input->show[input->amount_to_show]=0 ;
  2960.  
  2961.       if(input->bs && strlen(input->show) != input->amount_to_show)
  2962.         strcat(input->show, " ");
  2963.  
  2964.       GOTO_XY(input->xpos + input->pos - input->first - 1, input->ypos);
  2965.     }
  2966.     else
  2967.     {
  2968.       strncpy(input->show, input->text+where, a);
  2969.       input->show[a]=0;
  2970.       input->show[input->amount_to_show]=0;
  2971.  
  2972.       if(input->bs && strlen(input->show) != input->amount_to_show)
  2973.         strcat(input->show, " ");
  2974.  
  2975.       GOTO_XY(input->xpos + input->pos - input->first, input->ypos);
  2976.     }
  2977.     setc(mode==COMMON_INACTIVE ? info->inactive_color : mode ==COMMON_ITEM ? info->mi_normal : info->ci_normal);
  2978.  
  2979.     if(IE_PASSWORD & input->char_case)
  2980.       echo=0;
  2981.     else
  2982.       echo=1;
  2983.     outstr(input->show);
  2984.   }
  2985.   else if(type==COMMON_NONE)
  2986.   {
  2987.   }
  2988.   else
  2989.   {
  2990.     sysoplog("Undefined update type in function redrawinputpic");
  2991.   }
  2992.  
  2993.  
  2994.   if(mode==COMMON_CURRENT)
  2995.   {
  2996.  
  2997.     info->xpos=input->xpos + input->pos - input->first;
  2998.     info->ypos=input->ypos;
  2999.     GOTO_XY(info->xpos, info->ypos);
  3000.   }
  3001.  
  3002.   input->bs=FALSE;
  3003.   setc(savecolor);
  3004. }
  3005.  
  3006. /* ********************************************************************** */
  3007. /* Asylum INI Code (Part of COMMON) - by Michael Deweese Copyright 1994   */
  3008. /*                                                                        */
  3009. /* You may use this code in WWIV as installed under the COMMON.MOD file   */
  3010. /* You may not use this code in your own programs without the consent of  */
  3011. /* Michael Deweese.                                                       */
  3012. /* You can call these functions from your own WWIV modifications, but may */
  3013. /* not rip these out and include them in your mod.  In other words, to    */
  3014. /* access these functions, the user using your modification must have     */
  3015. /* mod installed                                                          */
  3016. /*                                                                        */
  3017. /*                                                                        */
  3018. /* USAGE:                                                                 */
  3019. /*    There are two basic ways to make use of these ini functions, the    */
  3020. /*    first and most simple is two call two high level functions that take*/
  3021. /*    care of all the work, they are:                                     */
  3022. /*                                                                        */
  3023. /*    get_ini_value                                                       */
  3024. /*    put_ini_value                                                       */
  3025. /*                                                                        */
  3026. /*    These two functions will open up the ini file, read it into memory, */
  3027. /*    do any modifications to it, as needed, and then write it back to    */
  3028. /*    disk.  Now this is on every single call, and thus, might be kind of */
  3029. /*    slow on large ini readings                                          */
  3030. /*                                                                        */
  3031. /*    eg                                                                  */
  3032. /*                                                                        */
  3033. /*    (Start ASYLUM.INI)                                                  */
  3034. /*    [LISTPLUS]                                                          */
  3035. /*    bar_color = 8                                                       */
  3036. /*    other_color = 5                                                     */
  3037. /*                                                                        */
  3038. /*    char s[10];                                                         */
  3039. /*    strcpy(s, "7");    // 7 to be used as a default if bar_color        */
  3040. /*                       // doesn't exist                                 */
  3041. /*    get_ini_value("ASYLUM.INI", "listplus", "bar_color", s, 10);        */
  3042. /*                                                                        */
  3043. /*    // s now equals "8"                                                 */
  3044. /*                                                                        */
  3045. /*    strcpy(s, "Zu Digital"                                              */
  3046. /*    get_ini_value("ASYLUM.INI", "Super Config", "WHO", s, 10);          */
  3047. /*                                                                        */
  3048. /*    // [Super Config] didn't exist, so it was created, likewise, WHO    */
  3049. /*    // didn't exist, so a 'WHO = Zu Digital' was added                  */
  3050. /*                                                                        */
  3051. /*                                                                        */
  3052. /*    strcpy(s, "1");                                                     */
  3053. /*    put_ini_value("ASYLUM.INI", "ListPlus", "other_color", s);          */
  3054. /*                                                                        */
  3055. /*    // other_color already existed in section [ListPlus], so it was     */
  3056. /*    // removed and replaced with other_color = 1                        */
  3057. /*                                                                        */
  3058. /*                                                                        */
  3059. /* Again, that reads and writes after every single call, if you need to   */
  3060. /* do alot of reading, then a little code such as the following is what   */
  3061. /* you want...                                                            */
  3062. /*                                                                        */
  3063. /*                                                                        */
  3064. /*  ini_inforec ini_info;                                                 */
  3065. /*  char s[10];                                                           */
  3066. /*                                                                        */
  3067. /*  // Read ini file into memory                                          */
  3068. /*  if(!open_ini_file("ASYLUM.INI", &ini_info))                           */
  3069. /*    return -1;    // Wasn't able to retrieve or create fname.ini        */
  3070. /*                                                                        */
  3071. /*                                                                        */
  3072. /*  // this will read the values...                                       */
  3073. /*  strcpy(s, "15");                                                      */
  3074. /*  read_ini_string(&ini_info, "ListPlus", "Color", s, 10);                */
  3075. /*                                                                        */
  3076. /*  // This will overwrite previous color with new value                  */
  3077. /*  strcpy(s, "NONE");                                                    */
  3078. /*  set_ini_string(&ini_info, "ListPlus", "Color", s, 10);                 */
  3079. /*                                                                        */
  3080. /*  // Now write your changes to disk                                     */
  3081. /*  write_ini_file(&ini_info);                                            */
  3082. /*                                                                        */
  3083. /*  // And free your memory                                               */
  3084. /*  free_ini_info(&ini_info);                                             */
  3085. /*                                                                        */
  3086. /* ********************************************************************** */
  3087.  
  3088.  
  3089. int get_ini_value(char *fname, char *area, char *indent, char *value, int max_value)
  3090. {
  3091.   ini_inforec ini_info;
  3092.  
  3093.   if(!open_ini_file(fname, &ini_info))
  3094.     return -1;    /* Wasn't able to retrieve or create fname.ini */
  3095.  
  3096.   read_ini_string(&ini_info, area, indent, value, max_value);
  3097.  
  3098.   if(ini_info.changes_made)
  3099.     write_ini_file(&ini_info);   // value had to be added, so write it to disk
  3100.  
  3101.   free_ini_info(&ini_info);
  3102.   return 1;       /* Successful read */
  3103. }
  3104.  
  3105. int put_ini_value(char *fname, char *area, char *indent, char *value)
  3106. {
  3107.   ini_inforec ini_info;
  3108.  
  3109.   if(!open_ini_file(fname, &ini_info))
  3110.     return -1;    /* Wasn't able to retrieve or create fname.ini */
  3111.  
  3112.   set_ini_string(&ini_info, area, indent, value);
  3113.   write_ini_file(&ini_info);   // set_ini_string only sets the memory, it must
  3114.                                // be written to disk
  3115.  
  3116.   free_ini_info(&ini_info);
  3117.   return 1;       /* Successful read */
  3118. }
  3119.  
  3120. void free_ini_info(ini_inforec *ini_info)
  3121. {
  3122.   if(ini_info->ini)
  3123.     free(ini_info->ini);
  3124. }
  3125.  
  3126.  
  3127.  
  3128. int write_ini_file(ini_inforec *ini_info)
  3129. {
  3130.   FILE *fp;
  3131.  
  3132.   fp = fsh_open(ini_info->fname, "w+t");
  3133.   if(!fp)
  3134.     return 0;               /*  Couldn't create ini file */
  3135.  
  3136.   fseek(fp, 0, SEEK_SET);
  3137.   fsh_write((void *)ini_info->ini, 1, ini_info->fsize, fp);
  3138.  
  3139.   fsh_close(fp);
  3140.   return 1;
  3141. }
  3142.  
  3143. char *open_ini_file(char *fname, ini_inforec *ini_info)
  3144. {
  3145.   FILE *fp;
  3146.  
  3147.   memset((void *)ini_info, 0, sizeof(ini_inforec));
  3148.   strcpy(ini_info->fname, fname);
  3149.  
  3150.   fp = fsh_open(fname, "rt" );
  3151.  
  3152.   if(!fp)                        /* if it doesn't exist, create it */
  3153.   {
  3154.     fp = fsh_open(fname, "w+t");
  3155.     if(!fp)
  3156.       return NULL;               /*  Couldn't create ini file */
  3157.   }
  3158.  
  3159.   ini_info->fsize=filesize(fp);
  3160.  
  3161.   if(ini_info->fsize < 60000L)   /* Make 60,000 our file size */
  3162.     ini_info->ini = (char *) malloca(ini_info->fsize + EXTRA_INI_SPACE);
  3163.  
  3164.   if(!ini_info->ini)
  3165.   {
  3166.     fclose(fp);
  3167.     return NULL;
  3168.   }
  3169.  
  3170.   fseek(fp, 0, SEEK_SET);
  3171.   ini_info->fsize = fread((void *)ini_info->ini, 1, ini_info->fsize, fp);
  3172.   ini_info->ini[ini_info->fsize]=0;
  3173.  
  3174.   ini_info->allocated=ini_info->fsize + EXTRA_INI_SPACE;
  3175.  
  3176.   fsh_close(fp);
  3177.   return(ini_info->ini);
  3178. }
  3179.  
  3180. char * increase_ini_allocation(ini_inforec *ini_info)
  3181. {
  3182.   ini_info->allocated += EXTRA_INI_SPACE;
  3183.  
  3184.   if(ini_info->allocated > 0xffff)
  3185.     return NULL;
  3186.  
  3187.   ini_info->ini = (char *)realloc(ini_info->ini, ini_info->allocated);
  3188.  
  3189.   return(ini_info->ini);
  3190. }
  3191.  
  3192.  
  3193. void set_ini_string(ini_inforec *ini_info, char *area, char *indent, char *value)
  3194. {
  3195.   FILE *fp;
  3196.   char buff[255], *tmp, w1[128], w2[128];
  3197.   long area_start, pos, save_pos;
  3198.   int amount;
  3199.  
  3200.  
  3201.   /* If area == "" then don't bother with an [area] */
  3202.   if(area[0])
  3203.     area_start = find_ini_area(ini_info->ini, area);
  3204.   else
  3205.     area_start = ini_info->fsize;
  3206.  
  3207.   if(area_start >= ini_info->fsize)
  3208.   {
  3209.  
  3210.     if(area[0])
  3211.     {
  3212.       amount = sprintf(buff, "\n[%s]\n", area);
  3213.  
  3214.       if(ini_info->fsize + amount >= ini_info->allocated)
  3215.         if(!increase_ini_allocation(ini_info))
  3216.           return;
  3217.  
  3218.       strcat(ini_info->ini, buff);
  3219.       ini_info->fsize+= amount;
  3220.     }
  3221.  
  3222.     amount = sprintf(buff, "%s = %s\n", indent, value);
  3223.  
  3224.     if(ini_info->fsize + amount >= ini_info->allocated)
  3225.       if(!increase_ini_allocation(ini_info))
  3226.         return;
  3227.  
  3228.     strcat(ini_info->ini, buff);
  3229.     ini_info->fsize+= amount;
  3230.  
  3231.     ini_info->changes_made = 1;
  3232.     return;
  3233.   }
  3234.  
  3235.  
  3236.   pos = area_start;
  3237.   while(1)
  3238.   {
  3239.     save_pos = pos;
  3240.     tmp = get_ini_line(buff, 255, &pos, ini_info->ini);
  3241.  
  3242.     if(!tmp)
  3243.       break;
  3244.  
  3245.     strip_string(buff);
  3246.  
  3247.     if(buff[0]=='[')  // Star of a new area, so break
  3248.     {
  3249.       save_pos = area_start;    // Put value right after [area], comment out this line to put at end
  3250.       break;
  3251.     }
  3252.     break_up_ini(buff, w1, w2);
  3253.  
  3254.     if(strcmpi(w1, indent) == 0)
  3255.     {
  3256.       if(!w2[0])
  3257.         strcpy(w2, value);
  3258.  
  3259.       memmove(ini_info->ini + save_pos, ini_info->ini + pos, ini_info->fsize - pos+1);
  3260.       ini_info->fsize = ini_info->fsize - (pos - save_pos);
  3261.       break;
  3262.     }
  3263.   }
  3264.  
  3265.   amount = sprintf(buff, "%s = %s\n", indent, value);
  3266.  
  3267.   if(ini_info->fsize + amount >= ini_info->allocated)
  3268.     if(!increase_ini_allocation(ini_info))
  3269.       return;
  3270.  
  3271.   memmove(ini_info->ini+amount+save_pos, ini_info->ini+save_pos,
  3272.                                ini_info->fsize+amount-save_pos+1);
  3273.   strncpy(ini_info->ini+save_pos, buff, amount);
  3274.   ini_info->fsize += amount;
  3275.  
  3276.   ini_info->changes_made = 1;
  3277.   return;         // Value was updated
  3278. }
  3279.  
  3280. void set_ini_number(ini_inforec *ini_info, char *area, char *indent, long value)
  3281. {
  3282.   FILE *fp;
  3283.   char buff[255], *tmp, w1[128], w2[128];
  3284.   long area_start, pos, save_pos;
  3285.   int amount;
  3286.  
  3287.  
  3288.   /* If area == "" then don't bother with an [area] */
  3289.   if(area[0])
  3290.     area_start = find_ini_area(ini_info->ini, area);
  3291.   else
  3292.     area_start = ini_info->fsize;
  3293.  
  3294.   if(area_start >= ini_info->fsize)
  3295.   {
  3296.  
  3297.     if(area[0])
  3298.     {
  3299.       amount = sprintf(buff, "\n[%s]\n", area);
  3300.  
  3301.       if(ini_info->fsize + amount >= ini_info->allocated)
  3302.         if(!increase_ini_allocation(ini_info))
  3303.           return;
  3304.  
  3305.       strcat(ini_info->ini, buff);
  3306.       ini_info->fsize+= amount;
  3307.     }
  3308.  
  3309.     amount = sprintf(buff, "%s = %ld\n", indent, value);
  3310.  
  3311.     if(ini_info->fsize + amount >= ini_info->allocated)
  3312.       if(!increase_ini_allocation(ini_info))
  3313.         return;
  3314.  
  3315.     strcat(ini_info->ini, buff);
  3316.     ini_info->fsize+= amount;
  3317.  
  3318.     ini_info->changes_made = 1;
  3319.     return;
  3320.   }
  3321.  
  3322.  
  3323.   pos = area_start;
  3324.   while(1)
  3325.   {
  3326.     save_pos = pos;
  3327.     tmp = get_ini_line(buff, 255, &pos, ini_info->ini);
  3328.  
  3329.     if(!tmp)
  3330.       break;
  3331.  
  3332.     strip_string(buff);
  3333.  
  3334.     if(buff[0]=='[')  // Star of a new area, so break
  3335.     {
  3336.       save_pos = area_start;    // Put value right after [area], comment out this line to put at end
  3337.       break;
  3338.     }
  3339.     break_up_ini(buff, w1, w2);
  3340.  
  3341.     if(strcmpi(w1, indent) == 0)
  3342.     {
  3343.       memmove(ini_info->ini + save_pos, ini_info->ini + pos, ini_info->fsize - pos+1);
  3344.       ini_info->fsize = ini_info->fsize - (pos - save_pos);
  3345.       break;
  3346.     }
  3347.   }
  3348.  
  3349.   amount = sprintf(buff, "%s = %ld\n", indent, value);
  3350.  
  3351.   if(ini_info->fsize + amount >= ini_info->allocated)
  3352.     if(!increase_ini_allocation(ini_info))
  3353.       return;
  3354.  
  3355.   memmove(ini_info->ini+amount+save_pos, ini_info->ini+save_pos,
  3356.                                ini_info->fsize+amount-save_pos+1);
  3357.   strncpy(ini_info->ini+save_pos, buff, amount);
  3358.   ini_info->fsize += amount;
  3359.  
  3360.   ini_info->changes_made = 1;
  3361.   return;
  3362. }
  3363.  
  3364.  
  3365. long read_ini_number(ini_inforec *ini_info, char *area, char *indent, long value)
  3366. {
  3367.   char *ini, *tmp, buff[255], w1[128], w2[128];
  3368.   long fsize, area_start, pos;
  3369.   int amount;
  3370.  
  3371.  
  3372.   /* If area == "" then don't bother with an [area] */
  3373.   if(area[0])
  3374.     area_start = find_ini_area(ini_info->ini, area);
  3375.   else
  3376.     area_start = ini_info->fsize;
  3377.  
  3378.   if(area_start >= ini_info->fsize)
  3379.   {
  3380.  
  3381.  
  3382.     if(area[0])
  3383.     {
  3384.       amount = sprintf(buff, "\n[%s]\n", area);
  3385.  
  3386.       if(ini_info->fsize + amount >= ini_info->allocated)
  3387.         if(!increase_ini_allocation(ini_info))
  3388.           return -1;
  3389.  
  3390.       strcat(ini_info->ini, buff);
  3391.       ini_info->fsize += amount;
  3392.     }
  3393.  
  3394.     amount = sprintf(buff, "%s = %ld\n", indent, value);
  3395.  
  3396.     if(ini_info->fsize + amount >= ini_info->allocated)
  3397.       if(!increase_ini_allocation(ini_info))
  3398.         return -1;
  3399.  
  3400.     strcat(ini_info->ini, buff);
  3401.     ini_info->fsize += amount;
  3402.  
  3403.  
  3404.     ini_info->changes_made = 1;
  3405.     return(value);
  3406.   }
  3407.  
  3408.  
  3409.  
  3410.   pos = area_start;
  3411.   while(1)
  3412.   {
  3413.     tmp = get_ini_line(buff, 255, &pos, ini_info->ini);
  3414.  
  3415.     if(!tmp)          // No more lines
  3416.     {
  3417.       ini_info->changes_made = 1;
  3418.       set_ini_number(ini_info, area, indent, value);
  3419.       return 3;
  3420.     }
  3421.  
  3422.     strip_string(tmp);
  3423.  
  3424.  
  3425.     if(buff[0]=='[')  // Star of a new area
  3426.     {
  3427.       ini_info->changes_made = 1;
  3428.       set_ini_number(ini_info, area, indent, value);
  3429.       return 3;
  3430.     }
  3431.  
  3432.     break_up_ini(buff, w1, w2);
  3433.  
  3434.     if(strcmpi(w1, indent) == 0)
  3435.       return(atol(w2));
  3436.   }
  3437. }
  3438.  
  3439.  
  3440.  
  3441. int read_ini_string(ini_inforec *ini_info, char *area, char *indent, char *value, int max_value)
  3442. {
  3443.   char *ini, *tmp, buff[255], w1[128], w2[128];
  3444.   long fsize, area_start, pos;
  3445.   int amount;
  3446.  
  3447.  
  3448.   /* If area == "" then don't bother with an [area] */
  3449.   if(area[0])
  3450.     area_start = find_ini_area(ini_info->ini, area);
  3451.   else
  3452.     area_start = ini_info->fsize;
  3453.  
  3454.   if(area_start >= ini_info->fsize)
  3455.   {
  3456.  
  3457.     if(area[0])
  3458.     {
  3459.       amount = sprintf(buff, "\n[%s]\n", area);
  3460.  
  3461.       if(ini_info->fsize + amount >= ini_info->allocated)
  3462.         if(!increase_ini_allocation(ini_info))
  3463.           return 0;
  3464.  
  3465.       strcat(ini_info->ini, buff);
  3466.       ini_info->fsize += amount;
  3467.     }
  3468.  
  3469.     amount = sprintf(buff, "%s = %s\n", indent, value);
  3470.  
  3471.     if(ini_info->fsize + amount >= ini_info->allocated)
  3472.       if(!increase_ini_allocation(ini_info))
  3473.         return 0;
  3474.  
  3475.     strcat(ini_info->ini, buff);
  3476.     ini_info->fsize += amount;
  3477.  
  3478.     ini_info->changes_made = 1;
  3479.     return 2;                 /* Value was added, area was created */
  3480.   }
  3481.  
  3482.  
  3483.  
  3484.   pos = area_start;
  3485.   while(1)
  3486.   {
  3487.     tmp = get_ini_line(buff, 255, &pos, ini_info->ini);
  3488.  
  3489.     if(!tmp)          // No more lines
  3490.     {
  3491.       set_ini_string(ini_info, area, indent, value);
  3492.       return 3;
  3493.     }
  3494.  
  3495.     strip_string(tmp);
  3496.  
  3497.     if(buff[0]=='[')  // Star of a new area
  3498.     {
  3499.       set_ini_string(ini_info, area, indent, value);
  3500.       return 3;
  3501.     }
  3502.  
  3503.     break_up_ini(buff, w1, w2);
  3504.  
  3505.     if(strcmpi(w1, indent) == 0)
  3506.     {
  3507.       if(w2[0])
  3508.       {
  3509.         strncpy(value, w2, max_value);
  3510.         value[max_value]=0;
  3511.       }
  3512.       return 1;
  3513.     }
  3514.   }
  3515. }
  3516.  
  3517.  
  3518.  
  3519.  
  3520.  
  3521.  
  3522. char * get_ini_line(char *buff, int max_len, long *pos, char *ini)
  3523. {
  3524.   int c, buff_pos=0;
  3525.   char *temp;
  3526.  
  3527.   if(!ini[*pos])     // If at end of buffer, return NULL
  3528.     return NULL;
  3529.  
  3530.   while(1)
  3531.   {
  3532.     c = ini[*pos];
  3533.  
  3534.     if(c == 0 || c == '\n')
  3535.     {
  3536.       buff[buff_pos] = 0;
  3537.       if(c)    // Only increment if we are on a newline
  3538.         ++*pos;
  3539.  
  3540.       temp=strchr(buff, ';');
  3541.       if(temp)
  3542.         temp[0]=0;      // Null out all after ; (comment)
  3543.  
  3544.       return(buff);
  3545.     }
  3546.  
  3547.     buff[buff_pos] = c;
  3548.  
  3549.     ++buff_pos;
  3550.     ++*pos;
  3551.  
  3552.     if(buff_pos >= max_len)
  3553.     {
  3554.       buff[buff_pos] = 0;
  3555.  
  3556.       temp=strchr(buff, ';');
  3557.       if(temp)
  3558.         temp[0]=0;      // Null out all after ; (comment)
  3559.  
  3560.       return(buff);
  3561.     }
  3562.   }
  3563. }
  3564.  
  3565.  
  3566.  
  3567. void break_up_ini(char *buff, char *w1, char *w2)
  3568. {
  3569.   int pos=0, spos;
  3570.   int c;
  3571.  
  3572.   strip_string(buff);
  3573.  
  3574.   while(1)
  3575.   {
  3576.     c = buff[pos];
  3577.  
  3578.     if(c == '=' || c == 0)
  3579.     {
  3580.       buff[pos]=0;
  3581.       if(c)
  3582.         ++pos;
  3583.       break;
  3584.     }
  3585.     ++pos;
  3586.   }
  3587.   strcpy(w1, buff);
  3588.  
  3589.   spos=pos;
  3590.  
  3591.   while(1)
  3592.   {
  3593.     c = buff[pos];
  3594.  
  3595.     if(c == 0)
  3596.     {
  3597.       buff[pos] = 0;
  3598.       break;
  3599.     }
  3600.  
  3601.     ++pos;
  3602.   }
  3603.  
  3604.   strcpy(w2, buff+spos);
  3605.  
  3606.   strip_string(w1);
  3607.   strip_string(w2);
  3608. }
  3609.  
  3610.  
  3611. long find_ini_area(char *ini, char *area)
  3612. {
  3613.   char buff[255], *other_side, *tmp;
  3614.   long pos=0;
  3615.  
  3616.   if(!area[0])
  3617.     strlen(ini);
  3618.  
  3619.   while(1)
  3620.   {
  3621.     tmp = get_ini_line(buff, 255, &pos, ini);
  3622.  
  3623.     if(!tmp)
  3624.       return(pos);
  3625.  
  3626.     strip_string(buff);
  3627.  
  3628.     if(buff[0] != '[')
  3629.       continue;
  3630.  
  3631.     tmp=strchr(buff, ']');
  3632.  
  3633.     if(!tmp)
  3634.       return(pos);
  3635.  
  3636.     tmp[0]=0;
  3637.  
  3638.     if(strcmpi(buff+1, area) == 0)
  3639.       return(pos);
  3640.  
  3641.   }
  3642. }
  3643.  
  3644.  
  3645.